HDOJ 5416 CRB and Tree

来源:互联网 发布:如何寻找淘宝达人 编辑:程序博客网 时间:2024/06/06 03:54

点分治的做法很好想,但是会超时。对于这个题,找一个点dfs,统计异或值的个数就行了。。

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 100005;const int maxm = 200005;struct Edge{int v, w;Edge *next;}E[maxm], *H[maxn], *edges;int cnt[maxn << 1];int a[maxn], n, m;void addedges(int u, int v, int w){edges->v = v;edges->w = w;edges->next = H[u];H[u] = edges++;}void init(){edges = E;memset(H, 0, sizeof H);}void dfs(int u, int fa, int dist){cnt[dist]++;a[u] = dist;for(Edge *e = H[u]; e; e = e->next) if(e->v != fa) dfs(e->v, u, dist ^ e->w);}void work(){scanf("%d", &n);for(int i = 1; i < n; i++) {int a, b, c;scanf("%d%d%d", &a, &b, &c);addedges(a, b, c);addedges(b, a, c);}memset(cnt, 0, sizeof cnt);dfs(1, 1, 0);scanf("%d", &m);while(m--) {LL ans = 0;int s;scanf("%d", &s);for(int i = 1; i <= n; i++) {if(s == 0) ans += cnt[a[i]] + 1;else ans += cnt[a[i] ^ s];}printf("%lld\n", ans / 2);}}int main(){int _;scanf("%d", &_);while(_--) {init();work();}return 0;}


0 0