Anti-Rhyme Pairs (求最长公共前缀)

题目链接: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:\n",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\n",ans);
70         }
71     }
72     return 0;
73 }

 

posted @ 2019-11-29 00:16  _Ackerman  阅读(255)  评论(0编辑  收藏  举报