【题解】 bzoj3916: [Baltic2014]friends (字符串Hash)
Solution
- 首先长度为偶数可以直接判掉
- 然后我们可以枚举删的位置,通过预处理的\(hash\),判断剩余部分是否划分成两个一样的
- 判重要注意,我们把字符串分为三个部分\(L_l+1+L_r\),(\(L_l=L_r\)),如果上次答案和这次都出现在\(L_l\),则一定不会是不同的,因为右边的\(L_r\)是一样的,所以复制的串一定是一样的,全在\(L_r\)同理
- 那么我们就只用判断上次出现的答案在\(L_l+1\)上,这次出现在\(L_r\)上,其实我们就可以发现复制的串变成了\(L_l\),那么我们就只用用\(Hash\)判断\(L_l\)与\(L_r\)是否相同即可,不同才是\(Unique\)
- 上面这种情况让我\(wa\)了好久
貌似又是一次跑的没暴力快qwq
Code
//It is coded by ning_mew on 7.25
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn=2e6+7;
LL MOD[3]={19260817,20000909,19491001};
LL Hash[3][maxn],Pow[3][maxn];
LL ans=0,L,n;
char ch[maxn];
bool check(int pl){
for(int k=0;k<3;k++){
LL box=Hash[k][n],box1=0,box2=0;
if(pl==L+1){
box1=Hash[k][L];
box2=((Hash[k][n]-Hash[k][L+1]*Pow[k][L]%MOD[k])%MOD[k]+MOD[k])%MOD[k];
}
else if(pl<=L){
box2=((Hash[k][n]-Hash[k][L+1]*Pow[k][L]%MOD[k])%MOD[k]+MOD[k])%MOD[k];
box1=((Hash[k][L+1]-Hash[k][pl]*Pow[k][L+1-pl]%MOD[k]+Hash[k][pl-1]*Pow[k][L+1-pl]%MOD[k])%MOD[k]+MOD[k])%MOD[k];
}else{
box1=Hash[k][L];
box2=((Hash[k][n]-Hash[k][pl]*Pow[k][n-pl]%MOD[k]+(Hash[k][pl-1]-Hash[k][L]*Pow[k][pl-1-L]%MOD[k])*Pow[k][n-pl])%MOD[k]+MOD[k])%MOD[k];
}
if(box1!=box2)return false;
}return true;
}
bool unique(int pl){
for(int k=0;k<3;k++){
LL box1=((Hash[k][pl]-Hash[k][L+1]*Pow[k][pl-L-1])%MOD[k]+MOD[k])%MOD[k];
LL box2=((Hash[k][pl-1]-Hash[k][L]*Pow[k][pl-L-1])%MOD[k]+MOD[k])%MOD[k];
if(box1!=box2)return false;
}return true;
}
int main(){
scanf("%lld",&n);
if(n%2==0){printf("NOT POSSIBLE\n");return 0;}
L=(n-1)/2;
scanf("%s",ch+1);
for(int k=0;k<3;k++){
Pow[k][0]=1;Hash[k][0]=0;
for(int i=1;i<=n;i++){
Hash[k][i]=(Hash[k][i-1]*237+ch[i]-'A')%MOD[k];
Pow[k][i]=Pow[k][i-1]*237%MOD[k];
}
}
for(int i=1;i<=n;i++){
if(check(i)){
if(!ans)ans=i;
else{
if((ans<=L+1&&i>L+1)){
if(!unique(i)){
printf("NOT UNIQUE\n");
return 0;
}
}
}
}
}
if(!ans){printf("NOT POSSIBLE\n");return 0;}
else {
int box=0;
for(int i=1;i<=n;i++){
if(i!=ans&&box<(n-1)/2){printf("%c",ch[i]);box++;}
}
}return 0;
}
博主蒟蒻,随意转载。但必须附上原文链接:http://www.cnblogs.com/Ning-Mew/,否则你会场场比赛爆0!!!