题意:
游戏规则是有一个字符串,把它复制之后放到原字符串的后面,之后在这个字符串随机插入一个字母,得到一个新的字符串。现在给你一个字符串,问你可不可能是经过游戏的操作得到的。
题解:
就是哈希前缀和来判断字符串是否相同。思维不难,但是想提醒自己注意一下这种哈希前缀和的写法,注意哈希前缀和相减时的下标和乘的基数的指数。
代码:
//正经的哈希不知道怎么挂了,自然溢出这种东西反而过了。。。
#include <bits/stdc++.h>
using namespace std;
int n;
char s[2000010],ans[2000010];
long long ha[2000010],mod=19261926817817,b=13131,ji,mi[2000010],pd=-1;
int main()
{
scanf("%d",&n);
scanf("%s",s+1);
if(n%2==0)
{
printf("NOT POSSIBLE\n");
return 0;
}
mi[0]=1;
for(int i=1;i<=n;++i)
{
ha[i]=ha[i-1]*b+s[i];
mi[i]=mi[i-1]*b;
}
for(int i=1;i<=n+1;++i)
{
if(i<=n/2)
{
long long x,y;
x=ha[i-1]*mi[n/2-i+1]+(ha[n/2+1]-ha[i]*mi[n/2-i+1]);
y=(ha[n]-ha[n/2+1]*mi[n/2]);
if(x==y)
{
ji=i;
if(pd==-1)
pd=x;
else if(pd!=x)
{
printf("NOT UNIQUE\n");
return 0;
}
}
}
else
{
long long x,y;
x=ha[n/2];
y=(ha[i-1]-ha[n/2]*mi[i-n/2-1])*mi[n-i]+(ha[n]-ha[i]*mi[n-i]);
if(x==y)
{
ji=i;
if(pd==-1)
pd=x;
else if(pd!=x)
{
printf("NOT UNIQUE\n");
return 0;
}
}
}
}
if(pd==-1)
printf("NOT POSSIBLE\n");
else
{
if(ji>n/2)
{
for(int i=1;i<=n/2;++i)
printf("%c",s[i]);
}
else
{
for(int i=n/2+2;i<=n;++i)
printf("%c",s[i]);
}
printf("\n");
}
return 0;
}