Clairewd’s message(哈希模板+)
个人心得:一开始就是知道用哈希,但是无从下手,很明显是对哈希不太了解和思维不太好。
先来看一下这一题涉及到的哈希吧和这题的思路吧,思路就是对所给的密文用原文和翻译后进行hash处理,那么必然存在后面那一段用所给的密文处理等于前面
长度相同的用解密后处理的hash值一样。
比如abcdab,那么必然ab翻译后值等于末尾ab的值,注意长度应从len/2+len%2开始,因为如果长度为奇数个要从后一位开始。
typedef unsigned long long ull; const int N = 100000 + 5; const ull base = 163; char s[N]; ull hash[N]; void init(){//处理hash值 p[0] = 1; hash[0] = 0; int n = strlen(s + 1); for(int i = 1; i <=100000; i ++)p[i] =p[i-1] * base; for(int i = 1; i <= n; i ++)hash[i] = hash[i - 1] * base + (s[i] - 'a'); } ull get(int l, int r, ull g[]){//取出g里l - r里面的字符串的hash值 return g[r] - g[l - 1] * p[r - l + 1]; }
题目:
Clairewd is a member of FBI. After several years concealing in BUPT, she intercepted some important messages and she was preparing for sending it to ykwd. They had agreed that each letter of these messages would be transfered to another one according to a conversion table.
Unfortunately, GFW(someone's name, not what you just think about) has detected their action. He also got their conversion table by some unknown methods before. Clairewd was so clever and vigilant that when she realized that somebody was monitoring their action, she just stopped transmitting messages.
But GFW knows that Clairewd would always firstly send the ciphertext and then plaintext(Note that they won't overlap each other). But he doesn't know how to separate the text because he has no idea about the whole message. However, he thinks that recovering the shortest possible text is not a hard task for you.
Now GFW will give you the intercepted text and the conversion table. You should help him work out this problem.
Unfortunately, GFW(someone's name, not what you just think about) has detected their action. He also got their conversion table by some unknown methods before. Clairewd was so clever and vigilant that when she realized that somebody was monitoring their action, she just stopped transmitting messages.
But GFW knows that Clairewd would always firstly send the ciphertext and then plaintext(Note that they won't overlap each other). But he doesn't know how to separate the text because he has no idea about the whole message. However, he thinks that recovering the shortest possible text is not a hard task for you.
Now GFW will give you the intercepted text and the conversion table. You should help him work out this problem.
InputThe first line contains only one integer T, which is the number of test cases.
Each test case contains two lines. The first line of each test case is the conversion table S. S[i] is the ith latin letter's cryptographic letter. The second line is the intercepted text which has n letters that you should recover. It is possible that the text is complete.
Hint
Range of test data: T<= 100 ;
n<= 100000;
OutputFor each test case, output one line contains the shorest possible complete text.Sample Input
2 abcdefghijklmnopqrstuvwxyz abcdab qwertyuiopasdfghjklzxcvbnm qwertabcde
Sample Output
abcdabcd qwertabcde
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<iomanip> #include<string> #include<algorithm> using namespace std; #define inf 1<<29 #define nu 1000005 #define maxnum 100005 #define num 30 typedef unsigned long long ull; int t,n; int len; ull m=161; ull h1[maxnum],h2[maxnum],p[maxnum]; char s[30],ch[maxnum]; int c[30]; void getp(){ p[0]=1; for(int i=1;i<=100005;i++) p[i]=p[i-1]*m; } ull geth(ull h[],int i,int j){ return h[j]-h[i-1]*p[j-i+1]; } void solved(){ h1[0]=h2[0]=0; for(int i=0;i<26;i++) c[s[i]-'a']=i; for(int i=1;i<=len;i++){ h1[i]=h1[i-1]*m+c[ch[i]-'a']; h2[i]=h2[i-1]*m+ch[i]-'a'; } int a=len/2+len%2; int flag; for(int i=a;i<=len;i++){ int le=len-i; ull key1=geth(h1,1,le); ull key2=geth(h2,i+1,len); //cout<<key1<<" "<<key2<<endl; if(key1==key2) { flag=i; break; } } // cout<<flag; for(int i=1;i<=flag;i++) printf("%c",ch[i]); for(int i=1;i<=flag;i++) { char cc=c[ch[i]-'a']+'a'; printf("%c",cc); } puts(""); } int main() { scanf("%d",&t); getp(); while(t--){ scanf("%s%s",s,ch+1); len=strlen(ch+1); solved(); } return 0; }