zoukankan      html  css  js  c++  java
  • 大海(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
    ", Ans);
    86 }
  • 相关阅读:
    端口映射到公网工具
    C# app.config文件配置和修改
    C#基本知识点-Readonly和Const的区别
    C#知识点-StopWatch-计时
    python with open as f写中文乱码
    程序员不要去这样的公司
    关于老系统的重构和优化选择
    .Net Remoting 调用远程对象
    自定义的Config节点及使用
    前台线程和后台线程区别与使用技巧
  • 原文地址:https://www.cnblogs.com/iamqzh233/p/9427691.html
Copyright © 2011-2022 走看看