题解:枚举去掉的是哪一位然后哈希推式子即可。
注意题目说的not unique是指的S不同。
代码:
//BZOJ 3916
#include<iostream>
#include<cstring>
#include<cstdio>
#define MAXN 2000100
#define sig 27
#define mod 1000000007
#define lint long long
using namespace std;
char s[MAXN];
int hv[MAXN],mi[MAXN];
inline int toi(char ch)
{
return ch-'A'+1;
}
int main()
{
int n;scanf("%d",&n);scanf("%s",s+1);
mi[0]=1;int cnt=0,k=n/2,pos,alr=-1;
if(n%2==0) goto fail;
for(int i=1;i<=n;i++)
mi[i]=(lint)mi[i-1]*sig%mod,
hv[i]=(hv[i-1]+(lint)toi(s[i])*mi[i-1]%mod)%mod;
for(int i=1;i<=k;i++)
{
int u=(lint)((lint)hv[i-1]*sig%mod+hv[k+1]-hv[i]+mod)%mod*mi[k]%mod;
int v=(hv[n]-hv[k+1]+mod)%mod;
// cout<<u<<" "<<v<<endl;
if(u==v)
{
if(!cnt) alr=v,cnt=1;
else if(alr!=v) { cnt=2;goto fail; }
pos=i;
}
}
for(int i=k+1;i<=n;i++)
{
int u=(lint)mi[k+1]*hv[k]%mod;
int v=((((lint)hv[i-1]-hv[k]+mod)%mod)*(lint)sig%mod+hv[n]-hv[i]+mod)%mod;
if(u==v)
{
if(!cnt) alr=v,cnt=1;
else if(alr!=v) { cnt=2;goto fail; }
pos=i;
}
}
fail:;
if(!cnt) printf("NOT POSSIBLE");
else if(cnt>1) printf("NOT UNIQUE");
else for(int i=1,cnt=1;cnt<=k;i++)
if(i^pos) printf("%c",s[i]),cnt++;
printf("\n");return 0;
}