hdu 5416 CRB and Tree 求树上路径异或结果为s的有多少

来源:互联网 发布:ug8.0编程视频教程下载 编辑:程序博客网 时间:2024/04/29 02:30

题意:给一颗树,定义f(u,v)为u到v路径上的异或结果,现在给定s,要求异或结果为s的路径有多少条。(1,2)和(2,1)只算一种。

根据异或的特性有f(u,v)=f(1,u)^f(1,v),先把f(1,i)的所有i都求出,然后对于每一个u(1~n)如果有f(u,v)=s的话那么有f(1,v)=s^f(1,u),所以求一下f(1,v)有多少个,加起来就行了,最后要特殊讨论下s==0的情况。

//author: CHC//First Edit Time:    2015-08-22 15:41#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <set>#include <vector>#include <map>#include <queue>#include <set>#include <algorithm>#include <limits>using namespace std;typedef long long LL;const int MAXN=100000*2+1000;const int INF = numeric_limits<int>::max();const LL LL_INF= numeric_limits<LL>::max();struct Edge {    int to,next,w;    Edge(){}    Edge(int _to,int _next,int _w):to(_to),next(_next),w(_w){}}e[MAXN<<1];int head[MAXN],tot;void init(){    memset(head,-1,sizeof(head));    tot=0;}void AddEdge(int u,int v,int w){    e[tot]=Edge(v,head[u],w);    head[u]=tot++;    e[tot]=Edge(u,head[v],w);    head[v]=tot++;}int dis[MAXN];int has[1<<17],N,Q,T;void dfs(int u,int fa){    ++has[dis[u]];    for(int i=head[u];~i;i=e[i].next){        int v=e[i].to;        if(v==fa)continue;        if(dis[v]!=-1)continue;        dis[v]=dis[u]^e[i].w;        dfs(v,u);    }}int main(){    scanf("%d",&T);    while(T--){        scanf("%d",&N);        init();        for(int i=0,x,y,w;i<N-1;i++){            scanf("%d%d%d",&x,&y,&w);            AddEdge(x,y,w);        }        memset(has,0,sizeof(has));        memset(dis,-1,sizeof(dis));        dis[1]=0;        dfs(1,-1);        scanf("%d",&Q);        LL ans=0;        int s;        while(Q--){            scanf("%d",&s);            ans=0;            for(int i=1;i<=N;i++)ans+=has[s^dis[i]];            if(!s)ans+=N;            ans/=2;            printf("%I64d\n",ans);        }    }    return 0;}
0 0
原创粉丝点击