题解 P6739 【[BalticOI 2014 Day1] Three Friends】
题解:
注意到
但是,由于 Hash 的存在,我们判断两个字符串相同无需按序比较,可以 Hash
什么是 Hash
据某位学长说,所有的单 Hash 都可以卡掉,所以建议大家使用双 Hash(但是我懒)
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=2e6+233;
const int base=233;
const int mod=998244353; //只用了单Hash
int n,cnt,flag,mark;
int h[maxn],pw[maxn],b[30];
char a[maxn];
int sum(int l,int r){ //计算区间[l,r]的Hash值
if(l>r)return 0;
return ((h[r]-(h[l-1]*pw[r-l+1])%mod)%mod+mod)%mod;
}
int query(int pos){ //Hash判断剩下的两段是否相同,pos即断点
int pre=0,nxt=0;
if(pos==(n+1)/2){
pre=h[pos-1];
nxt=sum(pos+1,n);
return pre==nxt;
}
if(pos<(n+1)/2){
pre=((h[pos-1]*pw[(n+1)/2-pos])%mod+sum(pos+1,(n+1)/2))%mod;
nxt=sum((n+1)/2+1,n);
return pre==nxt;
}
if(pos>(n+1)/2){
pre=h[(n+1)/2-1];
nxt=((sum((n+1)/2,pos-1)*pw[n-pos])%mod+sum(pos+1,n))%mod;
return pre==nxt;
}
}
signed main(){
memset(b,-1,sizeof(b));
cin>>n;
cin>>a+1;
int len=strlen(a+1);
for(int i=1;i<=len;++i) //Hash预处理
h[i]=((h[i-1]*base)%mod+(int)a[i]-'A'+1)%mod;
pw[0]=1;
for(int i=1;i<=n;i++)
pw[i]=(pw[i-1]*base)%mod;
for(int i=1;i<=n;i++)
if(query(i)){
mark=i,cnt++; //记录可能的端点数量及端点位置
if(b[a[i]-'A'+1]!=-1&&b[a[i]-'A'+1]!=i-1)flag=1;
b[a[i]-'A'+1]=i;
}
if(flag&&cnt>1){cout<<"NOT UNIQUE";return 0;}
if(cnt<1){cout<<"NOT POSSIBLE";return 0;}
if(mark==(n+1)/2){ //输出
for(int j=1;j<=mark-1;j++)putchar(a[j]);
}
else if(mark<(n+1)/2){
for(int j=1;j<=mark-1;j++)putchar(a[j]);
for(int j=mark+1;j<=(n+1)/2;j++)putchar(a[j]);
}
else if(mark>(n+1)/2){
for(int j=(n+1)/2;j<=mark-1;j++)putchar(a[j]);
for(int j=mark+1;j<=n;j++)putchar(a[j]);
return 0;
}
return 0;
}