大海(sea)

题目描述

输入

输出

样例输入

4 1 
1 2 1 
1 3 1 
2 4 2 
2 3

样例输出

1

提示

考虑回文串的性质,就是最多只有一种出现了奇数次的颜色。

那么对于每一种颜色随机一种hash值。

如果一个路径上的hash值异或起来是0或者是某种颜色的hash值,就可以组成一个回文串。

易证此算法的正确率很高。

我靠,这OJ不能用unordered_map真的是浑身难受

 1 #pragma GCC optimize(2)
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 #define LL long long
 5 #define M 1000010
 6 #define MOD 5000003
 7 struct Edge{
 8     int u, v; LL w; int Next;
 9 } G[M * 2];
10 int head[M], tot;
11 LL d[M];
12 inline void add(int u, int v, LL w) {
13     G[++ tot] = (Edge){u, v, w, head[u]};
14     head[u] = tot;
15 }
16 inline void dfs(int x, int fa) {
17     for(int i = head[x]; i != -1; i = G[i].Next) {
18         if(G[i].v == fa) continue;
19         d[G[i].v] = d[x] ^ G[i].w;
20         dfs(G[i].v, x);
21     }
22 }
23 LL ha[2][M * 5];
24 LL a[M * 5];
25 inline LL Find(LL x, int op = 0) {
26     if(op == 0) {
27         int wt = x % MOD;
28         while(ha[0][wt]) {
29             if(ha[0][wt] == x) return a[wt];
30             ++ wt;
31             if(wt == MOD) wt = 0; 
32         }
33         return 0;
34     }
35     else {
36         int wt = x % MOD;
37         while(ha[1][wt]) {
38             if(ha[1][wt] == x) return 1;
39             ++ wt;
40             if(wt == MOD) wt = 0;
41         }
42         return 0;
43     }
44 }
45 inline void Insert(LL x, LL y) {
46     int wt = x % MOD;
47     while(ha[0][wt]) {
48         ++ wt; if(wt == MOD) wt = 0;
49     }
50     ha[0][wt] = x; a[wt] = y;
51     wt = y % MOD;
52     while(ha[1][wt]) {
53         ++ wt; if(wt == MOD) wt = 0;
54     }
55     ha[1][wt] = y;
56 }
57 int main() {
58     int n, Q;
59     scanf("%d%d", &n, &Q);
60     memset(head, -1, sizeof(head));
61     for(int i = 1; i < n; ++ i) {
62         int u, v, w;
63         scanf("%d%d%d", &u, &v, &w);
64         if(!Find(w)) {
65             Insert(w, 1ll * rand() * rand());
66         }
67         LL o = Find(w);
68         //cerr << o << endl;
69         add(u, v, o); add(v, u, o);
70     }
71     dfs(1, 0);
72     int A, B;
73     int Ans = 0;
74     scanf("%d%d", &A, &B);
75     while(Q --) {
76         int x = A % n + 1, y = B % n + 1;
77         LL od = d[x] ^ d[y];
78         //cerr << x << " " << y << endl;
79         if(od == 0 || Find(od, 1)) {
80             ++ Ans;
81         } 
82         A = 1ll * A * 666073 % 1000000007;
83         B = 1ll * B * 233 % 998244353;
84     }
85     printf("%d\n", Ans);
86 }

猜你喜欢

转载自www.cnblogs.com/iamqzh233/p/9427691.html
今日推荐