首页 > 代码库 > AC日记——Dylans loves tree hdu 5274

AC日记——Dylans loves tree hdu 5274

Dylans loves tree

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1611    Accepted Submission(s): 388


Problem Description
Dylans is given a tree with N技术分享 nodes.

All nodes have a value A[i]技术分享.Nodes on tree is numbered by 1N技术分享.

Then he is given Q技术分享 questions like that:

0 x y技术分享:change node x技术分享技术分享s技术分享 value to y技术分享

1 x y技术分享:For all the value in the path from x技术分享 to y技术分享,do they all appear even times?

For each ② question,it guarantees that there is at most one value that appears odd times on the path.

1N,Q100000技术分享, the value A[i]N技术分享 and A[i]100000技术分享
 

 

Input
In the first line there is a test number T技术分享.
(T3技术分享 and there is at most one testcase that N>1000技术分享)

For each testcase:

In the first line there are two numbers N技术分享 and Q技术分享.

Then in the next N1技术分享 lines there are pairs of (X,Y)技术分享 that stand for a road from x技术分享 to y技术分享.

Then in the next line there are N技术分享 numbers A技术分享1技术分享..A技术分享N技术分享技术分享 stand for value.

In the next Q技术分享 lines there are three numbers(opt,x,y)技术分享.
 

 

Output
For each question ② in each testcase,if the value all appear even times output "-1",otherwise output the value that appears odd times.
 

 

Sample Input
13 21 22 31 1 11 1 21 1 3
 

 

Sample Output
-11
Hint
If you want to hack someone,N and Q in your testdata must smaller than 10000,and you shouldn‘t print any space in each end of the line.
 

 

Source
BestCoder Round #45
 
 
思路:
  判断树上路径是否有出现过奇数次的权值;
  数据保证一条路径上最多一个出现奇数次的权值;
  因为x^x=0,0^x=x的性质;
  我们可以用异或和;
  把一条路径的全部权值都异或;
  如果等于0则不存在,否则就输出;
  同时,因为0^0=0;
  所以我们全部的权值都+1;
  然后,输出时再-1;
 
 
来,上代码:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define maxn 100005using namespace std;struct TreeNodeType {    int l,r,dis,mid;};struct TreeNodeType tree[maxn<<2];struct EdgeType {    int v,next;};struct EdgeType edge[maxn<<1];int if_z,t,n,q,dis[maxn],dis_[maxn];int cnt=0,head[maxn],deep[maxn],f[maxn];int top[maxn],size[maxn],flag[maxn];char Cget;inline void in(int &now){    now=0,if_z=1,Cget=getchar();    while(Cget>9||Cget<0)    {        if(Cget==-) if_z=-1;        Cget=getchar();    }    while(Cget>=0&&Cget<=9)    {        now=now*10+Cget-0;        Cget=getchar();    }    now*=if_z;}inline void edge_add(int u,int v){    cnt++;    edge[cnt].v=v;    edge[cnt].next=head[u];    head[u]=cnt;}void search_1(int now,int fa){    int pos=cnt++;    deep[now]=deep[fa]+1,f[now]=fa;    for(int i=head[now];i;i=edge[i].next)    {        if(edge[i].v==fa) continue;        search_1(edge[i].v,now);    }    size[now]=cnt-pos;}void search_2(int now,int chain){    top[now]=chain,flag[now]=++cnt;    dis[flag[now]]=dis_[now]+1;    int pos=0;    for(int i=head[now];i;i=edge[i].next)    {        if(edge[i].v==f[now]) continue;        if(size[edge[i].v]>size[pos]) pos=edge[i].v;    }    if(pos==0) return ;    search_2(pos,chain);    for(int i=head[now];i;i=edge[i].next)    {        if(edge[i].v==pos||edge[i].v==f[now]) continue;        search_2(edge[i].v,edge[i].v);    }}inline void tree_up(int now){    tree[now].dis=tree[now<<1].dis^tree[now<<1|1].dis;}void tree_build(int now,int l,int r){    tree[now].l=l,tree[now].r=r;    if(l==r)    {        tree[now].dis=dis[l];        return ;    }    tree[now].mid=(l+r)>>1;    tree_build(now<<1,l,tree[now].mid);    tree_build(now<<1|1,tree[now].mid+1,r);    tree_up(now);}void tree_change(int now,int to,int x){    if(tree[now].l==tree[now].r)    {        tree[now].dis=x;        return ;    }    if(to<=tree[now].mid) tree_change(now<<1,to,x);    else tree_change(now<<1|1,to,x);    tree_up(now);}int tree_query(int now,int l,int r){    if(tree[now].l==l&&tree[now].r==r)    {        return tree[now].dis;    }    if(l>tree[now].mid) return tree_query(now<<1|1,l,r);    else if(r<=tree[now].mid) return tree_query(now<<1,l,r);    else return tree_query(now<<1,l,tree[now].mid)^tree_query(now<<1|1,tree[now].mid+1,r);}int solve_do(int x,int y){    int pos=0;    while(top[x]!=top[y])    {        if(deep[top[x]]<deep[top[y]]) swap(x,y);        pos=pos^tree_query(1,flag[top[x]],flag[x]);        x=f[top[x]];    }    if(deep[x]>deep[y]) swap(x,y);    pos=pos^tree_query(1,flag[x],flag[y]);    if(pos==0) return -1;    else return pos-1;}int main(){    in(t);    int lit=t;    while(t--)    {        memset(head,0,sizeof(head));        in(n),in(q);cnt=0;int u,v;        for(int i=1;i<n;i++)        {            in(u),in(v);            edge_add(u,v);            edge_add(v,u);        }        for(int i=1;i<=n;i++) in(dis_[i]);        cnt=0,search_1(1,0);        cnt=0,search_2(1,1);        tree_build(1,1,n);        int type;        for(int i=1;i<=q;i++)        {            in(type),in(u),in(v);            if(type) printf("%d\n",solve_do(u,v));            else tree_change(1,u,v+1);        }    }    return 0;}

 

AC日记——Dylans loves tree hdu 5274