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 xs 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 A1..AN 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
1 3 2 1 2 2 3 1 1 1 1 1 2 1 1 3
 

 

Sample Output
-1 1
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
 
 
思路:
  判断树上路径是否有出现过奇数次的权值;
  数据保证一条路径上最多一个出现奇数次的权值;
  因为x^x=0,0^x=x的性质;
  我们可以用异或和;
  把一条路径的全部权值都异或;
  如果等于0则不存在,否则就输出;
  同时,因为0^0=0;
  所以我们全部的权值都+1;
  然后,输出时再-1;
 
 
来,上代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

#define maxn 100005

using 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;
}

 

posted @ 2017-02-19 14:39  IIIIIIIIIU  阅读(227)  评论(0编辑  收藏  举报