BZOJ 3916: [Baltic2014]friends
BZOJ 3916: [Baltic2014]friends
Description
有三个好朋友喜欢在一起玩游戏,A君写下一个字符串S,B君将其复制一遍得到T,C君在T的任意位置(包括首尾)插入一个字符得到U.现在你得到了U,请你找出S.
Input
第一行一个数N,表示U的长度.
第二行一个字符串U,保证U由大写字母组成
Output
输出一行,若S不存在,输出"NOT POSSIBLE".若S不唯一,输出"NOT UNIQUE".否则输出S.
Sample Input
Sample Input1:
7
ABXCABC
Sample Input2:
6
ABCDEF
Sample Input3:
9
ABABABABA
7
ABXCABC
Sample Input2:
6
ABCDEF
Sample Input3:
9
ABABABABA
Sample Output
Sample Output1:
ABC
Sample Output2:
NOT POSSIBLE
Sample Output3:
NOT UNIQUE
ABC
Sample Output2:
NOT POSSIBLE
Sample Output3:
NOT UNIQUE
HINT
对于100%的数据 2<=N<=2000001
思路 :
对整个字符串进行hash,枚举插入字符位置,分三种情况讨论:在前半段, 在中间,在后半段, 分别把枚举到的剔除,把两段hash接到一起,与另外半串对比 若hash相同则存下来,等到下一次出现相同的时候判断是否重复,重复输出NOT UNIQUE ,如果一直没有ans 输出NOT POSSIBLE 如果所有答案的hash是相同的,在出答案的时候记录插入字符的位置,直接输出另外半段字符串即可 代码如下
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; char s[2100001]; unsigned int h1[2100001],mi[2100001]; unsigned int hav[2100001],tot; const int p = 1313131; int idx,n; unsigned int creat(int l,int r) { if(l>r)return 0; return h1[r]-h1[l-1]*mi[r-l+1]; } bool check(int x) { if(x<=idx) { unsigned int x1 = creat(1,x-1); unsigned int x2 = creat(x+1,idx+1); unsigned int x3 = creat(idx+2,n); (x1*=mi[idx-x+1])+=x2; if(x1==x3){hav[++tot]=x1;return 1;} } else if(x==idx+1) { unsigned int x1 = creat(1,x-1); unsigned int x3 = creat(x+1,n); if(x1==x3) {hav[++tot]=x1;return 1;} } else { unsigned int x1 = creat(1,idx); unsigned int x2 = creat(idx+1,x-1); unsigned int x3 = creat(x+1,n); (x2*=mi[n-x])+=x3; if(x2==x1) {hav[++tot]=x1;return 1;} } return 0; } void print(int x) { if(x==1) { for(int i=1;i<=n/2;i++) { putchar(s[i]); } } else { for(int i=n/2+2;i<=n;i++) { putchar(s[i]); } } } int main() { // freopen("2.in","r",stdin); scanf("%d%s",&n,s+1); idx=(n-1)/2; /*puts("NOT UNIQUE"); return 0;*/ if(!(n&1)) { puts("NOT POSSIBLE"); return 0; } mi[0]=1; int i,cnt=0; for(i=1;i<=n;i++) { mi[i]=mi[i-1]*p; h1[i]=h1[i-1]*p+s[i]; } /*for(i=1;i<=n;i++) { if(h1[i])printf("%d\n",i); }*/ int tmp=0; for(i=1;i<=n;i++) { if(check(i)) { //printf("%d\n",i); cnt++,tmp=i; } } sort(hav+1,hav+tot+1); int amt=0; for(i=1;i<=tot;i++) { if(hav[i]!=hav[i-1])amt++; } if(cnt>1&&amt>1) { puts("NOT UNIQUE"); } else if(!cnt) { puts("NOT POSSIBLE"); } else { if(tmp<=idx+1) { print(2); } else { print(1); } } }
欢迎来原博客看看 >原文链接<