• [hdu5416 CRB and Tree]树上路径异或和,dfs


    题意:给一棵树,每条边有一个权值,求满足u到v的路径上的异或和为s的(u,v)点对数

    思路:计a到b的异或和为f(a,b),则f(a,b)=f(a,root)^f(b,root)。考虑dfs,一边计算当前点到根的f值,用一个数组记录当前遍历过的点中到根的异或值为i的点的个数,那么答案可以O(1)算出来,更新也是O(1)的。

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    #pragma comment(linker, "/STACK:10240000")
    #include <map>
    #include <set>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    #define X                   first
    #define Y                   second
    #define pb                  push_back
    #define mp                  make_pair
    #define all(a)              (a).begin(), (a).end()
    #define fillchar(a, x)      memset(a, x, sizeof(a))
    #define copy(a, b)          memcpy(a, b, sizeof(a))
    
    typedef long long ll;
    typedef pair<int, int> pii;
    typedef unsigned long long ull;
    
    #ifndef ONLINE_JUDGE
    void RI(vector<int>&a,int n){a.resize(n);for(int i=0;i<n;i++)scanf("%d",&a[i]);}
    void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
    void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?1:-1;
    while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
    void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
    void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
    void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
    #endif
    template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
    template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
    
    const double PI = acos(-1.0);
    const int INF = 1e9 + 7;
    const double EPS = 1e-12;
    
    /* -------------------------------------------------------------------------------- */
    
    const int maxn = 2e5 + 7;
    
    struct Graph {
        vector<vector<int> > G;
        void clear() { G.clear(); }
        void resize(int n) { G.resize(n + 2); }
        void add(int u, int v) { G[u].push_back(v); }
        vector<int> & operator [] (int u) { return G[u]; }
    };
    Graph G;
    
    struct Edge {
        int u, v, w;
        Edge(int u, int v, int w) {
            this->u = u;
            this->v = v;
            this->w = w;
        }
    };
    vector<Edge> E;
    
    bool vis[maxn];
    int cnt[maxn];
    int Q[20];
    ll ans[20];
    int q, now;
    
    void add(int u, int v, int w) {
        E.pb(Edge(u, v, w));
        G.add(u, E.size() - 1);
    }
    
    void dfs(int u) {
        cnt[now] ++;
        for (int i = 0; i < q; i ++) {
            ans[i] += cnt[now ^ Q[i]];
        }
        vis[u] = true;
        for (int i = 0; i < G[u].size(); i ++) {
            Edge e = E[G[u][i]];
            if (!vis[e.v]) {
                now ^= e.w;
                dfs(e.v);
                now ^= e.w;
            }
        }
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
    #endif // ONLINE_JUDGE
        int T, n;
        cin >> T;
        while (T --) {
            cin >> n;
            E.clear();
            G.clear();
            G.resize(n);
            for (int i = 1; i < n; i ++) {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                add(u, v, w);
                add(v, u, w);
            }
            cin >> q;
            for (int i = 0; i < q; i ++) {
                scanf("%d", Q + i);
            }
            fillchar(vis, 0);
            now = 0;
            fillchar(cnt, 0);
            fillchar(ans, 0);
            dfs(1);
            for (int i = 0; i < q; i ++) {
                cout << ans[i] << endl;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Python语言之并发编程
    python语言之系统工具
    python语言之正则
    python语言之字符串与字节
    Python语言之持久化
    Python语言之数字格式化与时间
    Python语言之异常处理与测试
    Java-AQS源码详解(细节很多!)
    redis的主从复制原理
    Amdahl定律和可伸缩性
  • 原文地址:https://www.cnblogs.com/jklongint/p/4747310.html
Copyright © 2020-2023  润新知