Radio Transmission--kmp/hash
阿新 • • 發佈:2018-12-03
莫過一日曝十日寒。
問題 L: 【KMP】Radio Transmission
時間限制: 1 Sec 記憶體限制: 128 MB
提交: 39 解決: 10
[提交] [狀態] [討論版] [命題人:admin]
題目描述
給你一個字串,它是由某個字串不斷自我連線形成的。但是這個字串是不確定的,現在只想知道它的最短長度是多少。
輸入
第一行給出字串的長度L,第二行給出一個字串,全由小寫字母組成。
輸出
輸出最短的長度。
樣例輸入
複製樣例資料
8
cabcabca
樣例輸出
3
提示
我們可以利用abc不斷自我連線得到abcabcabc,讀入的cabcabca是它的子串。
對於全部資料,1≤L≤106
許久不看hash都忘掉了
hash
hash一遍,然後列舉答案
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<unsigned int,unsigned int> puii; const int maxn = 1e6+7; const puii sup = {233,2333}; puii operator + (puii a,puii b){return make_pair(a.first+b.first,a.second+b.second);} puii operator + (puii a,int b){return make_pair(a.first+b,a.second+b);} puii operator - (puii a,puii b){return make_pair(a.first-b.first,a.second-b.second);} puii operator * (puii a,puii b){return make_pair(a.first*b.first,a.second*b.second);} puii p[maxn] = {{0,0}}; char s[maxn]; puii Pow(puii a,int b){ puii ans = {1,1}; while(b){ if(b&1) ans = ans*a; a = a*a; b>>=1; } return ans; } int main() { int n; scanf("%d%s",&n,s+1); for(int i=1;i<=n;i++) p[i] = p[i-1]*sup + s[i]; for(int len=1;len<=n;len++){ puii x = p[len]; puii cc = Pow(sup,len); int j = len; while(j<=n){ if(x != p[j]-p[j-len]*cc) break; j += len; } if(j>n){ j -= len; if(j == n || p[n]-p[j]*Pow(sup,n-j) == p[n-j]) return 0*printf("%d\n",len); } } return 0*printf("%d\n",n); }
kmp
這個n-失配[n]畫個圖容易理解
#include<bits/stdc++.h> using namespace std; typedef long long ll; void GetNext(char t[],int *next,int n){ int i = 1,j = 0; while(i<n) (t[i]==t[j]) ? (next[i++] = ++j) : ((j == 0) ? (next[i++] = j) : (j = next[j-1])); } char s1[1000006]; int main() { int n; scanf("%d",&n); scanf("%s",s1); int *next = new int[n]; GetNext(s1,next,n); printf("%d\n",n-next[n-1]); return 0; }