http://www.lydsy.com/JudgeOnline/problem.php?id=3916
#include <bits/stdc++.h> using namespace std; int n, ans[3]; char s[2000005]; void work(int now) { int l=1, r=n-(n>>1); if(now<2) ++r; int flag=0; //printf("%d\n", now); for(int i=0, tot=n>>1; i<tot; ++i) { if(s[l]!=s[r]) { //printf("%d %d\n", l, r); if(now==0 || flag) { ans[now]=0; return; } if(now==1) ans[now]=l, ++l; if(now==2) ans[now]=r, ++r; flag=1; --i; continue; } ++l; ++r; } if(!flag) ans[now]=n-(n>>1); } bool check(int x, int y) { if(ans[x]==0 || ans[y]==0 || ans[x]==ans[y]) return 1; return 0; } int main() { scanf("%d%s", &n, s+1); if((n&1)==0) { puts("NOT POSSIBLE"); return 0; } for(int i=0; i<3; ++i) work(i); if(!ans[0] && !ans[1] && !ans[2]) { puts("NOT POSSIBLE"); return 0; } for(int i=0; i<3; ++i) for(int j=0; j<3; ++j) if(i!=j && !check(i, j)) { puts("NOT UNIQUE"); return 0; } int pos=0; for(int i=0; i<3; ++i) if(ans[i]) pos=ans[i]; //for(int i=0; i<3; ++i) printf("%d\n", ans[i]); for(int i=1, cnt=0; i<=n; ++i) { if(i==pos) continue; putchar(s[i]); if(++cnt==(n>>1)) break; } return 0; }
显然能枚举这个点然后左右hash吧= =
可是这样可能会被卡+常数大..
我们考虑3种情况= =这个点在中点左边、在中点上、中点右边。
然后计算这三种情况的答案= =然后就行辣= =(比如如果在左边,那么我们在扫的时候允许左边错一个字符
【BZOJ】3916: [Baltic2014]friends
原文:http://www.cnblogs.com/iwtwiioi/p/4373046.html