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
Sample Input2:
6
ABCDEF
Sample Input3:
9
ABABABABA
7
ABXCABC
Sample Input2:
6
ABCDEF
Sample Input3:
9
ABABABABA
Sample Output
Sample Output1:
ABC
Sample Output2:
NOT POSSIBLE
Sample Output3:
NOT UNIQUE
ABC
Sample Output2:
NOT POSSIBLE
Sample Output3:
NOT UNIQUE
HINT
对于100%的数据 2<=N<=2000001
题解:
随便hash,注意细节.
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#define P 107
#define N 2000010
#define ull unsigned long long
using namespace std;
ull h[N],t[N];
int n,ans,len;
map<ull,int>q;
char ch[N];
int main(){
scanf("%d",&n);
if (n%2==0||n==1){puts("NOT POSSIBLE");return 0;}
len=(n-1)/2;
scanf("%s",ch+1);
t[0]=1;h[0]=0;
for (int i=1;i<=n;i++) t[i]=t[i-1]*P;
for (int i=1;i<=n;i++) h[i]=h[i-1]*P+(ull)ch[i];
//for (int i=1;i<=n;i++) cout<<h[i]<<endl;
for (int i=1;i<=n;i++){
if (i<=len){
ull l=h[i-1],mid=h[len+1]-t[len+1-i]*h[i],r=h[n]-h[n-len]*t[len];
//cout<<l<<' '<<mid<<' '<<r<<endl;
l=l*t[len-i+1]+mid;
if (l==r){
if (q[l]||(!ans)) ans=i,q[l]=1;
else {puts("NOT UNIQUE");return 0;}
}
}
if (i==len+1){
ull l=h[i-1],r=h[n]-t[len]*h[i];
if (l==r){
if (q[l]||(!ans)) ans=i,q[l]=1;
else {puts("NOT UNIQUE");return 0;}
}
}
if (i>len+1){
ull l=h[len],mid=h[i-1]-h[len]*t[i-1-len],r=h[n]-h[i]*t[n-i];
r=mid*t[n-i]+r;
if (l==r){
if (q[l]||(!ans)) ans=i,q[l]=1;
else {puts("NOT UNIQUE");return 0;}
}
}
}
if (!ans){puts("NOT POSSIBLE");return 0;}
else{
int t=1;
while (len--){
if (t==ans) t=t+1;
printf("%c",ch[t]);
t++;
}
}
}