牛客練習賽33 E. tokitsukaze and Similar String (字串雜湊)
阿新 • • 發佈:2018-12-09
題目連結:https://ac.nowcoder.com/acm/contest/308/E
題意:中文題 見連結
題解:雜湊預處理(三雜湊模板)
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define mst(a,b) memset((a),(b),sizeof(a)) 6 #define mp(a,b) make_pair(a,b) 7 #define pi acos(-1) 8 #definepii pair<int,int> 9 #define pb push_back 10 const int INF = 0x3f3f3f3f; 11 const double eps = 1e-6; 12 const int maxn = 1e5 + 10; 13 const int maxm = 1e5 + 10; 14 const ll mod = 1e9 + 7; 15 16 ll P[3] = {359,1039,2797}; 17 ll MO[3] = {mod,mod + 2,1000000087}; 18 ll T[maxn][3]; 19 char s[maxn]; 20 21struct node { 22 ll has[3]; 23 }a[maxn][27]; 24 25 26 int main() { 27 #ifdef local 28 freopen("data.txt", "r", stdin); 29 // freopen("data.txt", "w", stdout); 30 #endif 31 for(int i = 0; i < 3; i++) T[0][i] = 1; 32 for(int i = 1; i < maxn; i++) 33 for(int j = 0; j < 3; j++) T[i][j] = T[i - 1][j] * P[j] % MO[j]; 34 int n; 35 scanf("%d",&n); 36 scanf("%s",s + 1); 37 for(int i = 0; i < 3; i++) 38 for(int j = 0; j < 26; j++) a[0][j].has[i] = 1; 39 for(int j = 0; j < 26; j++) { 40 for(int i = 1; i <= n; i++) { 41 s[i]++; 42 if(s[i] > 'z') s[i] -= 26; 43 for(int k = 0; k < 3; k++) a[i][j].has[k] = (a[i - 1][j].has[k] * P[k] % MO[k] + (s[i] - 'a')) % MO[k]; 44 } 45 } 46 int q; 47 scanf("%d",&q); 48 while(q--) { 49 int x,y,len; 50 scanf("%d%d%d",&x,&y,&len); 51 ll ned[3],now[3]; 52 for(int i = 0; i < 3; i++) { 53 ned[i] = a[y + len - 1][0].has[i] - a[y - 1][0].has[i] * T[len][i] % MO[i]; 54 if(ned[i] < 0) ned[i] += MO[i]; 55 } 56 int ans = 1e9; 57 for(int i = 0; i < 26; i++) { 58 bool flag = true; 59 for(int j = 0; j < 3; j++) { 60 now[j] = a[x + len - 1][i].has[j] - a[x - 1][i].has[j] * T[len][j] % MO[j]; 61 if(now[j] < 0) now[j] += MO[j]; 62 if(now[j] != ned[j]) { 63 flag = false; 64 break; 65 } 66 } 67 if(flag) 68 ans = min(ans,min(i, 26 - i)); 69 } 70 if(ans == 1e9) ans = -1; 71 printf("%d\n",ans); 72 } 73 return 0; 74 }