其他分享
首页 > 其他分享> > friends #2823. 「BalticOI 2014 Day 1」三个朋友

friends #2823. 「BalticOI 2014 Day 1」三个朋友

作者:互联网

[BalticOI 2014 Day1] Three Friends

题目描述

有一个字符串 \(S\),对他进行操作:

  1. 将 \(S\) 复制为两份,存在字符串 \(T\) 中
  2. 在 \(T\) 的某一位置上插入一个字符,得到字符串 \(U\)

现在给定 \(U\),求 \(S\)。

输入格式

第一行一个整数 \(N\) 代表 \(U\) 的长度。
第二行 \(N\) 个字符代表字符串 \(U\)。

输出格式

样例 #1

样例输入 #1

7
ABXCABC

样例输出 #1

ABC

样例 #2

样例输入 #2

6
ABCDEF

样例输出 #2

NOT POSSIBLE

样例 #3

样例输入 #3

9
ABABABABA

样例输出 #3

NOT UNIQUE

提示

数据规模与约定

本题采用捆绑测试。

对于 \(100\%\) 的数据,\(2 \le N \le 2 \times 10^6+1\),保证 \(U\) 中只包含大写字母。

说明

翻译自 BalticOI 2014 Day1 B Three Friends

思路

这题是一体经典的字符串哈希题,我们可以先求出每个字符串得哈希值,但是这题有些字符串有多余字符,因为每一个哈希值都是\(p\)进制数,所以我们可以通过进制转换来消除多余得字符。比如\(abcde\)这么一个字符串有\(c\)这个字符是多余得,那该怎么得到\(abde\)这么一个字符串呢?我们可以先把原字符串以\(c\)分割成\(ab\)和\(de\),因为除去\(c\)后面的字符串长度为\(2\),所以答案就是\(ab\times p^2+cd=abcd\)

代码

#include <iostream>
using namespace std;
typedef unsigned long long ULL;
const int N = 2000010,BASE = 131;
int n;
char s[N];
ULL h[N],p[N];
void string_hash_prework () {
	p[0] = 1;
	for (int i = 1;i <= n;i++) {
		h[i] = h[i-1] * BASE + (s[i] - 'A' + 1);
		p[i] = p[i-1] * BASE;
	}
}
ULL query (int l,int r) {
	return h[r]-h[l-1]*p[r-l+1];
}
int main () {
	scanf ("%d%s",&n,s+1);
	if ((n & 1) == 0) printf ("NOT POSSIBLE");
	else {
		string_hash_prework ();
		int t = 0;
		ULL ans = 0;
		bool flag = false;
		for (int i = 1;i <= n;i++) {
			ULL h1,h2;
			if (i <= n/2) h1 = query (1,i-1)*p[n/2-i+1]+query (i+1,n/2+1);
			else h1 = query (1,n/2);
			if (i <= n/2+1) h2 = query (n/2+2,n);
			else h2 = query (n/2+1,i-1)*p[n-i]+query (i+1,n);
			if (h1 == h2) {
				if (flag && ans != h1) {
					printf ("NOT UNIQUE");
					return 0;
				}
				flag = true;
				ans = h1,t = i;
			}
		}
		if (!flag) printf ("NOT POSSIBLE");
		else {
			int cnt = 1;
			for (int i = 1;cnt <= n/2;i++) {
				if (i != t) {
					printf ("%c",s[i]);
					cnt++;
				}
			}
		}
		printf ("\n");
	}
	return 0;
}

标签:输出,le,样例,哈希,BalticOI,字符串,2014,friends
来源: https://www.cnblogs.com/incra/p/16454159.html