【 哈希和哈希表】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; }