hash(2018年CSUST省赛选拔赛第一场B题+hash+字典树)

题目链接:http://csustacm.com:4803/problem/1006

题目:

思路:正如题目一样,本题是一个hash,比赛的时候用的字典树,但是不知道为什么一直RE(听学长说要动态开点,但是没学字典树,瞎套的板子,可能真的是我姿势不对吧~),赛后学了一边hash(字符串题只会上星期学的kmp)后把这题补了一下。这题就最后比较时需要将每个节点的从1到该节点路径上所有的字母组成一个新的字符串,然后与题目给的n个字符串进行匹配(匹配定义题目中有说),问是否所有的字符串都至少与给的n个字符串中的一个匹配,因此我们需要借助dfs来处理新的串,我们用一个vis来标记原来那n个字符串的字串的hash值,在跑dfs时顺便判定,降低复杂度。

代码实现如下:

 1 #include <set>
 2 #include <map>
 3 #include <queue>
 4 #include <stack>
 5 #include <cmath>
 6 #include <bitset>
 7 #include <cstdio>
 8 #include <string>
 9 #include <vector>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 #include <unordered_map>
15 using namespace std;
16 
17 typedef long long ll;
18 typedef pair<ll, ll> pll;
19 typedef pair<ll, int> pli;
20 typedef pair<int, ll> pil;;
21 typedef pair<int, int> pii;
22 typedef unsigned long long ull;
23 
24 #define lson i<<1
25 #define rson i<<1|1
26 #define bug printf("*********
");
27 #define FIN freopen("D://code//in.txt", "r", stdin);
28 #define debug(x) cout<<"["<<x<<"]" <<endl;
29 #define IO ios::sync_with_stdio(false),cin.tie(0);
30 
31 const double eps = 1e-8;
32 const int mod = 10007;
33 const int maxn = 2e5 + 7;
34 const double pi = acos(-1);
35 const int inf = 0x3f3f3f3f;
36 const ll INF = 0x3f3f3f3f3f3f3f;
37 const ull p = 2333;
38 
39 unordered_map<ull, int> vis;
40 int n, m, u, v, k, x;
41 int w[maxn];
42 ull hs1, hs2[maxn];
43 int tot;
44 int head[maxn];
45 
46 struct edge {
47     int v, next;
48 }ed[maxn<<1];
49 
50 void addedge(int u, int v) {
51     ed[tot].v = v;
52     ed[tot].next = head[u];
53     head[u] = tot++;
54     ed[tot].v = u;
55     ed[tot].next = head[v];
56     head[v] = tot++;
57 }
58 
59 bool dfs(int u, int fa) {
60     for(int i = head[u]; ~i; i = ed[i].next) {
61         int v = ed[i].v;
62         if(v == fa) continue;
63         hs2[v] = hs2[u] * p + w[v];
64         if(!vis[hs2[v]]) return false;
65         if(!dfs(v, u)) return false;
66     }
67     return true;
68 }
69 
70 int main() {
71     //FIN;
72     scanf("%d%d", &n, &m);
73     memset(head, -1, sizeof(head));
74     for(int i = 1; i <= n; i++) {
75         scanf("%d", &k);
76         hs1 = 0;
77         for(int j = 1; j <= k; j++) {
78             scanf("%d", &x);
79             hs1 = hs1 * p + x;
80             vis[hs1] = 1;
81         }
82     }
83     for(int i = 1; i <= m; i++) {
84         scanf("%d", &w[i]);
85     }
86     for(int i = 1; i < m; i++) {
87         scanf("%d%d", &u, &v);
88         addedge(u, v);
89     }
90     if(!vis[w[1]]) {
91         puts("NO");
92     } else {
93         hs2[1] = w[1];
94         if(dfs(1, 0)) puts("YES");
95         else puts("NO");
96     }
97     return 0;
98 }

补字典树写法:

  1 #include <set>
  2 #include <map>
  3 #include <queue>
  4 #include <stack>
  5 #include <cmath>
  6 #include <bitset>
  7 #include <cstdio>
  8 #include <string>
  9 #include <vector>
 10 #include <cstdlib>
 11 #include <cstring>
 12 #include <iostream>
 13 #include <algorithm>
 14 #include <unordered_map>
 15 using namespace std;
 16 
 17 typedef long long ll;
 18 typedef pair<ll, ll> pll;
 19 typedef pair<ll, int> pli;
 20 typedef pair<int, ll> pil;;
 21 typedef pair<int, int> pii;
 22 typedef unsigned long long ull;
 23 
 24 #define lson i<<1
 25 #define rson i<<1|1
 26 #define bug printf("*********
");
 27 #define FIN freopen("D://code//in.txt", "r", stdin);
 28 #define debug(x) cout<<"["<<x<<"]" <<endl;
 29 #define IO ios::sync_with_stdio(false),cin.tie(0);
 30 
 31 const double eps = 1e-8;
 32 const int mod = 10007;
 33 const int maxn = 2e5 + 7;
 34 const double pi = acos(-1);
 35 const int inf = 0x3f3f3f3f;
 36 const ll INF = 0x3f3f3f3f3f3f3f;
 37 
 38 int len, root, k, m, n, x, y;
 39 int w[maxn];
 40 vector<int> v, G[maxn];
 41 
 42 struct Trie {
 43     int cnt;
 44     map<int, int > nxt;
 45 
 46     void init() {
 47         cnt = 0;
 48         nxt.clear();
 49     }
 50 }T[maxn];
 51 
 52 void insert(int s) {
 53     int now = root;
 54     for(auto x : v[s]) {
 55         if(T[now].nxt[x] == 0) {
 56             T[len].init();
 57             T[now].nxt[x] = len++;
 58         }
 59         now = T[now].nxt[x];
 60         T[now].cnt++;
 61     }
 62 }
 63 
 64 bool dfs(int u, int p, int now) {
 65     int res = 1;
 66     for(auto v : G[u]) {
 67         if(v == p) continue;
 68         if(T[now].nxt[w[v]] == 0) return 0;
 69         res &= dfs(v, u, T[now].nxt[w[v]]);
 70     }
 71     return res;
 72 }
 73 
 74 int main() {
 75     FIN;
 76     scanf("%d%d", &n, &m);
 77     len = 1, root = 0;
 78     T[0].init();
 79     for(int i = 1; i <= n; i++) {
 80         scanf("%d", &k);
 81         for(int j = 1; j <= k; j++) {
 82             scanf("%d", &x);
 83             v[i].push_back(x);
 84         }
 85         insert(i);
 86     }
 87     for(int i = 1; i <= m; i++) {
 88         scanf("%d", &w[i]);
 89     }
 90     for(int i = 1; i < m; i++) {
 91         scanf("%d%d", &x, &y);
 92         G[x].push_back(y);
 93         G[y].push_back(x);
 94     }
 95     if(T[0].nxt[w[1]] == 0) puts("NO");
 96     else {
 97         if(dfs(1, 0, T[0].nxt[w[1]])) puts("YES");
 98         else puts("NO");
 99     }
100     return 0;
101 }
原文地址:https://www.cnblogs.com/Dillonh/p/9440514.html