题目描述
PIPI叕来考查大家字符串处理能力了~
PIPI一开始有一个字符串S,现在它把S扩充了一倍得到了T,然后顽皮的POPO又在T中的某一个位置(可以是任意位置)插入了某一个字符得到了字符串P。
现在给你P,你需要找到初始的字符串S。
如果S不存在,输出NOT POSSIBLE
如果S不唯一,输出NOT UNIQUE
如果S唯一,输出字符串S
输入
单组数据。
第一行给出字符串P。|P|<=2e6.仅包含大写字母。
输出
输出占一行,按题目要求输出答案。
样例输入
ABXCABC
样例输出
ABC
#include <bits/stdc++.h>
using namespace std;
const int N=2e6+5;
typedef unsigned long long ull;
const ull base=23333;
ull hs[N],pw[N]; ///hs记录哈希数组的值 pw记录base进制的值
char s[N];
ull gethash(int l,int r)
{
return hs[r]-hs[l-1]*pw[r-l+1];///求长度从l到r的哈希值
}
int main()
{
scanf("%s",s+1); ///字符串从下标1开始存储
int n=strlen(s+1),mid=n/2+1;
ull last=0; ///last记录上一个位置的哈希值
int ans=0,pos=0;///pos记录断点的位置
if(n%2==0) {printf("NOT POSSIBLE\n");return 0;}
pw[0]=1;
for(int i=1;i<=n;i++)
{
pw[i]=pw[i-1]*base;
hs[i]=hs[i-1]*base+s[i]-'A'+1;
}
for(int i=1;i<=n;i++)
{
ull A,B,C; ///将整个字符串分为三段 断点在前半部分 中间 后半部分时
if(i<mid)
{
A=gethash(1,i-1);
B=gethash(i+1,mid);
C=gethash(mid+1,n);
if(A*pw[mid-i]+B==C&&last!=C) pos=i,ans++,last=C;
}
else if(i>mid)
{
A=gethash(1,mid-1);
B=gethash(mid,i-1);
C=gethash(i+1,n);
if(A==B*pw[n-i]+C&&last!=A) pos=i,ans++,last=A;
}
else
{
A=gethash(1,mid-1);
B=gethash(mid+1,n);
if(A==B&&last!=A) pos=i,ans++,last=A;
}
if(ans>1) break;
}
if(ans==0) printf("NOT POSSIBLE\n");
else if(ans>1) printf("NOT UNIQUE\n");
else
{
if(pos<=mid) for(int i=mid+1;i<=n;i++) printf("%c",s[i]);
else
for(int i=1;i<=mid-1;i++) printf("%c",s[i]);
}
return 0;
}