异或+构造 HDOJ 5416 CRB and Tree

题目传送门

题意:给一棵树,问f (u, v) 意思是u到v的所有路径的边权值的异或和,问f (u, v) == s 的u,v有几对

异或+构造:首先计算f (1, u) 的值,那么f (u, v) == f (1, u) ^ f (1, v),f (u, v) == s -> f (1, u) == s ^ f (1, v), 异或的性质,再考虑s == 0特殊情况就好了

/************************************************
* Author        :Running_Time
* Created Time  :2015-8-21 9:06:39
* File Name     :K.cpp
************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int a[N];
int cnt[N*10];
bool vis[N];
vector<pair<int, int> > G[N];
int n;

void add_edge(int u, int v, int w)  {
   G[u].push_back (make_pair (v, w));
   G[v].push_back (make_pair (u, w));
}

void init(void) {
   for (int i=1; i<=n; ++i)    G[i].clear ();
   memset (a, 0, sizeof (a));
   memset (cnt, 0, sizeof (cnt));
   memset (vis, false, sizeof (vis));
}

void BFS(int s) {
   queue<int> Q;   Q.push (s);
   vis[s] = true;
   while (!Q.empty ()) {
       int u = Q.front (); Q.pop ();
       for (int i=0; i<G[u].size (); ++i)  {
           int v = G[u][i].first, w = G[u][i].second;
           if (vis[v]) continue;
           vis[v] = true;;
           a[v] = a[u] ^ w;    Q.push (v);
       }
   }
}

void DFS(int u)  {
   vis[u] = true;
   for (int i=0; i<G[u].size (); ++i)  {
       int v = G[u][i].first, w = G[u][i].second;
       if (vis[v]) continue;
       vis[v] = true;  a[v] = a[u] ^ w;
       DFS (v);
   }
}

int main(void)    {
   int T;  scanf ("%d", &T);
   while (T--) {
       init ();
       scanf ("%d", &n);
       for (int u, v, w, i=1; i<n; ++i) {
           scanf ("%d%d%d", &u, &v, &w);
           add_edge (u, v, w);
       }

       //DFS (1);
       BFS (1);
       for (int i=1; i<=n; ++i)    cnt[a[i]]++;
       int q;  scanf ("%d", &q);
       while (q--) {
           int s;  scanf ("%d", &s);
           ll ans = 0;
           for (int i=1; i<=n; ++i)    {
               ans += cnt[a[i] ^ s];
           }
           if (s == 0) {
               ans -= n;
               ans /= 2;
               ans += n;
           }
           else    ans /= 2;
           printf ("%I64d ", ans);
       }
   }

   return 0;
}
编译人生,运行世界!
原文地址:https://www.cnblogs.com/Running-Time/p/4746957.html