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
会考结束了。终于可以安心码代码了
这题似乎有个KMP的方法。。咱家不会做。
不过可以枚举U然后比较两边是否相等。用下字符串HASH就OK了
#include<cstdio>
using namespace std;
char x[2000005];
long long mod=1000000007;
long long s[2000005];
inline long long power(long long x,int y)
{
long long t=1;
while(y!=0)
{
if(y%2==1)
t=(t*x)%mod;
x=(x*x)%mod;
y=y/2;
}
return t;
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
int lx;
scanf("%d",&lx);
if(lx%2==0)
{
printf("NOT POSSIBLE\n");
return 0;
}
scanf("%s",x);
long long t=26;
int i;
s[1]=x[0]-'A';
for(i=2;i<=lx;i++)
{
s[i]=(s[i-1]+(x[i-1]-'A')*t)%mod;
t=(t*(long long)26)%mod;
}
//for(i=1;i<=lx;i++)
// printf("%I64d\n",s[i]);
int sx=0;
int xt=0;
long long x1,x2;
long long tt1,tt2;
tt1=power(26,lx/2+1);
tt1=power(tt1,mod-2);
tt2=power(26,lx/2);
tt2=power(tt2,mod-2);
long long tx=power(26,mod-2);
long long xxt=-1;
for(i=1;i<=lx;i++)
{
if(i<=lx/2)
{
long long ttx=s[lx/2+1]-s[i];
while(ttx<0)
ttx+=mod;
x1=(s[i-1]+ttx*tx%mod)%mod;
ttx=s[lx]-s[lx/2+1];
while(ttx<0)
ttx+=mod;
x2=ttx*tt1%mod;
if(x1==x2)
{
if(x1!=xxt)
{
sx++;
xt=i-1;
xxt=x1;
}
}
}
else
{
x1=s[lx/2];
long long ttx=s[lx]-s[i];
while(ttx<0)
ttx+=mod;
x2=ttx*tx%mod;
ttx=s[i-1]-s[lx/2];
while(ttx<0)
ttx+=mod;
x2=(x2+ttx)*tt2%mod;
if(x1==x2)
{
if(x1!=xxt)
{
sx++;
xt=i-1;
xxt=x1;
}
}
}
}
if(sx==1)
{
int ss=0;
for(i=0;i<=lx/2-1;i++)
{
if(i!=xt)
{
printf("%c",x[i]);
ss++;
}
}
if(ss!=lx/2)
printf("%c",x[i]);
printf("\n");
}
else if(sx>1)
printf("NOT UNIQUE\n");
else
printf("NOT POSSIBLE\n");
return 0;
}