暂无链接
第三题
【问题描述】
有一个字符串S,你需要构造一个字符串T,使得T重复两次再在某个位置插入一个
字符后能得到S。
【输入格式】
一行一个字符串S。
【输出格式】
输出T,若无解,输出NOT POSSIBLE.若多解,输出NOT UNIQUE.
【输入样例1】
PUPILPQUPIL
【输出样例1】
PUPIL
【输入样例2】
PUPILPUPIL
【输出样例2】
NOT POSSIBLE
【输入样例3】
HAHAH
【输出样例3】
NOT UNIQUE
【样例说明3】
T可能是HA或AH。
【数据范围】
用n表示S的长度。
对于30%的数据,2<=n<=10;
对于60%的数据,2<=n<=2000;
对于100%的数据,2<=n<=2000000。
题解
史上最水题目名+不给部分分逼选手开$3$小时车系列。
直接$O(n)$枚举那个字母应该被删掉,用哈希花式过。
代码
#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const int N=2e6+5;
char ch[N];
ull base=19260817,mod=19491001,K[N],H[N];
int L;
void in(){scanf("%s",ch+1);}
void ac()
{
L=strlen(ch+1);
if((L&1^1)||L<=2)puts("NOT POSSIBLE"),exit(0);
K[0]=1;for(int i=1;i<=L;++i)K[i]=K[i-1]*base;
for(int i=1;i<=L;++i)H[i]=H[i-1]*base+ch[i];
int M=1+L>>1,ans=0,res=1e9;bool f1=0,f2=0;
ull hh,h1=H[M-1],h2=H[L]-H[M]*K[L-M];h1=h1+h1*K[M-1],h2=h2+h2*K[M-1];
for(int i=1;i<=L;++i)
{
hh=H[L]-H[i]*K[L-i]+H[i-1]*K[L-i];
if(i<M){if(hh==h2)res=i,f1=1;}else if(hh==h1){res=i,f2=1;}
if(f1&&f2)break;
}
if(!f1&&!f2)puts("NOT POSSIBLE"),exit(0);
if(f1&&f2&&h1!=h2)puts("NOT UNIQUE"),exit(0);
if(res<M)for(int i=M+1;i<=L;++i)putchar(ch[i]);
else for(int i=1;i<M;++i)putchar(ch[i]);
}
int main(){in();ac();}