大海(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 }