【 哈希和哈希表】Three Friends
时间限制: 1 Sec 内存限制: 128 MB提交: 67 解决: 11
[提交] [状态] [命题人:admin]
题目描述
Three friends like to play the following game. The first friend chooses a string S. Then the second friend constructs a new string T that consists of two copies of the string S. finally, the third friend inserts one letter at the beginning, the end or somewhere inside the string T, thereby creating a string U.
You are given the string U and your task is to reconstruct the original string S.
You are given the string U and your task is to reconstruct the original string S.
输入
The first line of the input contains N(2 ≤ N ≤ 2000001), the length of the final string U. The string U itself is given on the second line. It consists of N uppercase English letters (A, B, C, . . . , Z).
输出
Your program should print the original string S. However, there are two exceptions:
1.If the final string U could not have been created using the above procedure, you should print NOT POSSIBLE.
2.If the original string S is not unique, you should print NOT UNIQUE.
1.If the final string U could not have been created using the above procedure, you should print NOT POSSIBLE.
2.If the original string S is not unique, you should print NOT UNIQUE.
样例输入
复制样例数据
7
ABXCABC
样例输出
ABC
刚开始写字符串哈希,这题卡了好一会儿,我觉得主要是对于哈希的理解吧,做法很好想,枚举每一位假设这个是加入的字符,然后判断剩下的两半字符串是否相等就行,
用字符串哈希之后的哈希数表判断可以O(1)判断。
问题的关键在于如何正确进行两个字符串的拼接。
这里给出规律,如果是拼接在主串中所占范围为1到len的子串a和范围为(len+2)到n的子串b,h[n]-h[len+1]*f[n-len-1]+h[len]*f[n-len]
可以看出来,实际上就是将串a的tmp幂次转到和串b相同,也就是乘上相差的tmp的幂次,然后进行加减。(就这么理解吧暂时)
贴本题AC代码,反复改了好久。这题还有个坑点是注意重复的情况,记得开个map用vis标记一下。
#include<bits/stdc++.h>
using namespace std;
typedef long long unsigned llu;
typedef long long ll;
const int N=2e6+5;
const int mod=1e9+7;
const int tmp=31;
string a;
int n;
unsigned long long f[N];
unsigned long long h[N];
ll la;
ll ans[N],k;
map<llu,int>vis;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
f[0]=1;
for(int i=1; i<=N-1; i++)
f[i]=f[i-1]*tmp;
cin>>n;
cin>>a;
la=a.size();
if(la%2==0)
{
cout<<"NOT POSSIBLE"<<endl;
return 0;
}
memset(h,0,sizeof h);
for(int i=1;i<=la;i++)h[i]=h[i-1]*tmp+a[i-1]-'A'+1;
// cout<<h[3]<<endl;
int pos=-1;
llu len=(la>>1);
for(int i=1; i<=la; i++)
{
llu v1,v2;
if(i<=len)
{
v1=h[i-1]*f[len-i+1]+h[len+1]-h[i]*f[len-i+1];
v2=h[la]-h[len+1]*f[la-len-1];
}
else if(i==len+1)
{
v1=h[len];
v2=h[la]-h[len+1]*f[la-len-1];
}
else
{
v1=h[len];
v2=h[la]-h[i]*f[la-i]+(h[i-1]-h[len]*f[i-1-len])*f[la-i];
}
// cout<<v1<<" "<<v2<<endl;
if(v1==v2)
{
if(pos!=-1&&!vis[v1])
{
cout<<"NOT UNIQUE"<<endl;
return 0;
}
else pos=i,vis[v1]=true;
}
}
if(pos==-1)
{
cout<<"NOT POSSIBLE"<<endl;
return 0;
}//cout<<pos<<endl;
for(int i=0; i<n; i++)
{
if(i==pos-1)
continue;
if(len==0)
break;
cout<<a[i];
len--;
}
return 0;
}