字符串哈希..然后枚举每一位+各种判断就行了
--------------------------------------------------------------------------------
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MOD = 1000000007;
const int P = 59;
const int maxn = 2000009;
int N, H[maxn], Power[maxn], n = 0;
char s[maxn];
int getH(int p, int len) {
return (H[p] - ll(H[p + len]) * Power[len] % MOD + MOD) % MOD;
}
int main() {
scanf("%d%s", &N, s);
H[N] = 0;
for(int i = N; i--; )
H[i] = (ll(P) * H[i + 1] + s[i]) % MOD;
Power[0] = 1;
for(int i = 1; i <= N; i++)
Power[i] = ll(P) * Power[i - 1] % MOD;
if(N % 2 == 0) {
puts("NOT POSSIBLE");
return 0;
}
int ans0 = -1, ans1 = -1, h = H[N / 2 + 1];
for(int i = N >> 1; i--; )
if((ll(Power[i]) * getH(i + 1, N / 2 - i) % MOD + getH(0, i)) % MOD == h) {
ans0 = i; break;
}
h = getH(0, N >> 1);
for(int i = N >> 1; ++i < N; )
if((ll(Power[i - N / 2]) * getH(i + 1, N - i - 1) % MOD + getH(N / 2, i - N / 2)) % MOD == h) {
ans1 = i; break;
}
if(~ans0 && ~ans1) {
if(getH(0, N >> 1) != H[N / 2 + 1])
puts("NOT UNIQUE");
else {
for(int i = 0; i < (N / 2); i++)
putchar(s[i]);
}
} else if(!~ans0 && !~ans1) {
if(getH(0, N >> 1) == H[N / 2 + 1]) {
for(int i = 0; i < (N / 2); i++)
putchar(s[i]);
} else {
puts("NOT POSSIBLE");
}
} else if(~ans0) {
for(int i = N >> 1; ++i < N; )
putchar(s[i]);
} else {
for(int i = 0; i < N / 2; i++)
putchar(s[i]);
}
return 0;
}
--------------------------------------------------------------------------------
3916: [Baltic2014]friends
Time Limit: 30 Sec Memory Limit: 256 MB
Submit: 403 Solved: 148
[Submit][Status][Discuss]
Description
有三个好朋友喜欢在一起玩游戏,A君写下一个字符串S,B君将其复制一遍得到T,C君在T的任意位置(包括首尾)插入一个字符得到U.现在你得到了U,请你找出S.
Input
第一行一个数N,表示U的长度.
第二行一个字符串U,保证U由大写字母组成
Output
输出一行,若S不存在,输出"NOT POSSIBLE".若S不唯一,输出"NOT UNIQUE".否则输出S.
Sample Input
Sample Input1:
7
ABXCABC
7
ABXCABC
Sample Input2:
6
ABCDEF
Sample Input3:
9
ABABABABA
Sample Output
Sample Output1:
ABC
Sample Output2:
NOT POSSIBLE
Sample Output3:
NOT UNIQUE
HINT
对于100%的数据 2<=N<=2000001