题目链接:https://vjudge.net/contest/344930#problem/F
题目大意:给你n个字符串,让你求给定的两个串的最长公共前缀
题目思路:处理所给的n个字符串的Hash值,然后对于每次给定的两个串,二分长度就可以了。
值得注意的是这道题需要利用vector进行存储
1 #include <stdio.h> 2 #include <algorithm> 3 #include <iostream> 4 #include <stdlib.h> 5 #include <string> 6 #include <string.h> 7 #include <math.h> 8 #include <vector> 9 #include <queue> 10 #include <stack> 11 #include <map> 12 #include <set> 13 14 15 #define INF 0x3f3f3f3f 16 #define LL long long 17 18 typedef unsigned long long ull; 19 const int maxn = 1e5+10; 20 21 char s[maxn]; 22 ull base = 131; 23 ull mod = 1e9+7; 24 ull p[maxn]; 25 ull h1[maxn],h2[maxn]; 26 ull q[maxn]; 27 int len[maxn]; 28 std::vector<ull> h[maxn]; 29 30 31 ull get_hash(ull h[],int l,int r){ 32 return (h[r] - h[l-1]*p[r-l+1]); 33 } 34 35 36 int main() { 37 int T; 38 int cas = 1; 39 scanf("%d",&T); 40 while (T--) { 41 int n; 42 scanf("%d",&n); 43 for (int i=1;i<=n;i++) { 44 scanf("%s",s+1); 45 len[i] = strlen(s+1); 46 h[i].clear(); 47 h[i].push_back(0); 48 for (int j=1;j<=len[i];j++) { 49 h[i].push_back(h[i][j-1] * base + s[j] - 'a'); 50 } 51 } 52 int q; 53 printf("Case %d: ",cas++); 54 scanf("%d",&q); 55 while (q--) { 56 int u,v; 57 scanf("%d%d",&u,&v); 58 int l = 1,r = std::min(len[u],len[v]); 59 int ans = 0; 60 while (l <= r) { 61 int m = (l + r) >> 1; 62 if (h[u][m] == h[v][m]) { 63 ans = m; 64 l = m + 1; 65 } 66 else 67 r = m - 1; 68 } 69 printf("%d ",ans); 70 } 71 } 72 return 0; 73 }