您的位置:首页 > 其它

hdu5416 树上XOR

2015-09-01 15:04 302 查看
给一个s,问一棵树上两点间的路径的亦或值等于s的有几种情况,主要有一个公式 f(1,u)^f(1,v)=f(u,v),另外特判下s==0的情况

#include<stdio.h>
#include<string>
#include<map>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
const int N=1e5+10;
const int MOD=1e9+7;
int n,m,k,up;
int dep
;
int head
;
int q
;
int cnt[1<<19];
struct Edge{
int to,w,nxt;
}edge[N*2];
int tot;
void addEdge(int u,int v,int w){
edge[tot].to=v;
edge[tot].w=w;
edge[tot].nxt=head[u];
head[u]=tot++;
}
void init(){
tot=0;
memset(head,-1,sizeof head);
}
void calc(){
memset(dep,-1,sizeof dep);
int f=1,r=0;
q[++r]=1;
dep[r]=0;
while(f<=r){
int u=q[f++];
for(int i=head[u];~i;i=edge[i].nxt){
int v=edge[i].to,w=edge[i].w;
if(dep[v]!=-1) continue;
dep[v]=w^dep[u];
q[++r]=v;
}
}
memset(cnt,0,sizeof cnt);
for(int i=1;i<=n;i++) cnt[dep[i]]++;
}

int main(){
#ifndef ONLINE_JUDGE
freopen("aaa","r",stdin);
//freopen("bbb","w",stdout);
#endif
int tc;
for(scanf("%d",&tc);tc--;){
scanf("%d",&n);
init();
for(int i=1;i<n;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addEdge(u,v,w);
addEdge(v,u,w);
}
calc();
int q,s;

for(scanf("%d",&q);q--;){
long long ans=0;
scanf("%d",&s);
for(int i=1;i<=n;i++) ans+=cnt[dep[i]^s];
if(!s) ans+=n;
ans/=2;
printf("%I64d\n",ans);
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: