hys2919

用快度。到最小的节点不用push。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
//#include <unordered_set>
#define mkp make_pair
#define err cout<<"here"<<endl
using namespace std;
const double EPS=1e-12;
typedef long long lon;
typedef unsigned long long ull;
typedef map<ull,int>::iterator IT;
const lon SZ=550010,SSZ=1000010,APB=20,mod=100000,one=97;
const lon INF=0x7FFFFFFF;
int n,bg[SZ],fn[SZ],cnt,dp[SZ][APB];
int sum[SZ*5],dep[SZ];
struct nd{
    lon to,wt;
    nd(lon a=0,lon b=0):to(a),wt(b){}
};
int head[SZ],nex[SSZ],to[SSZ],wt[SSZ];
int tot=-1,dst[SZ],arr[SZ],lazy[SZ*5];
inline void add_edge(int u,int v,int w)
{
    ++tot;
    nex[tot]=head[u];
    head[u]=tot;
    to[tot]=v,wt[tot]=w;
}

void dfs1(int x,int p,int d,int y)
{
    bg[x]=++cnt;
    if(p!=-1)dp[x][0]=p;
    dep[x]=d;
    dst[x]=y;
    for(int i=1;i<APB;++i)
    {
        dp[x][i]=dp[dp[x][i-1]][i-1];
    }
    for(int i=head[x];i!=-1;i=nex[i])
    {
        int t=to[i];
        int w=wt[i];
        if(t!=p)
        {
            dfs1(t,x,d+1,y^arr[t]);
        }
    }
    fn[x]=cnt;
}

inline void pushdown(int rt)
{
    if(lazy[rt])
    {
        int cur=lazy[rt];
        lazy[rt*2]^=cur;
        lazy[rt*2+1]^=cur;
        sum[rt*2]^=cur;
        sum[rt*2+1]^=cur;
        lazy[rt]=0;
    }
}

inline void update(int ll,int rr,int rt,int ql,int qr,int val)
{
    if(ll!=rr)pushdown(rt);
    if(ql<=ll&&rr<=qr)
    {
        lazy[rt]=val;
        sum[rt]^=val;
        return;
    }
    if(ll>rr)return;
    int mid=(ll+rr)/2;
    if(ql<=mid)update(ll,mid,rt*2,ql,qr,val);
    if(qr>mid)update(mid+1,rr,rt*2+1,ql,qr,val);
}

inline int qry(int ll,int rr,int rt,int pos)
{
    if(ll!=rr)pushdown(rt);
    if(ll==rr)
    {
        return sum[rt];
    }
    if(ll>rr)return 0;
    int mid=(ll+rr)/2;
    if(pos<=mid)return qry(ll,mid,rt*2,pos);
    else return qry(mid+1,rr,rt*2+1,pos);
}

inline int lca(int x,int y)
{
    if(dep[x]<dep[y])swap(x,y);
    for(int i=APB-1;i>=0;--i)
    {
        if(dep[dp[x][i]]>=dep[y])
        {
            x=dp[x][i];
        }
    }
    if(x==y)return x;
    for(int i=APB-1;i>=0;--i)
    {
        if(dp[x][i]!=dp[y][i])
        {
            x=dp[x][i];
            y=dp[y][i];
        }
    }
    return dp[x][0];
}

void init()
{
    cin>>n;
    for(int i=1;i<=n;++i)scanf("%d",&arr[i]);;
    for(int i=1;i<=n;++i)
    head[i]=-1;
    //memset(head,-1,sizeof(head));
    for(int i=1;i<=n-1;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        add_edge(a,b,1);
        add_edge(b,a,1);
    }
    dfs1(1,-1,1,0);
    for(int i=1;i<=n;++i)
    {
        //cout<<"i: "<<i<<" "<<dst[i]<<endl;
        update(1,n,1,bg[i],bg[i],dst[i]);
    }
    int qnum;
    cin>>qnum;
    for(int i=1;i<=qnum;++i)
    {
        char type;
        scanf(" %c",&type);
        if(type=='Q')
        {
            int a,b;
            scanf("%d%d",&a,&b);
            int res=0;
            res^=qry(1,n,1,bg[a]);
            res^=qry(1,n,1,bg[b]);
            res^=arr[lca(a,b)];
            //cout<<res<<endl;
            if(res)printf("Yes\n");
            else printf("No\n");
            //printf("%s\n",res?"Yes":"No");
        }
        else
        {
            int id,val;
            scanf("%d%d",&id,&val);
            update(1,n,1,bg[id],fn[id],arr[id]^val);
            arr[id]=val;
        }
    }
}

void work()
{
    
}

void release()
{    
    
}

int main()
{
    //std::ios::sync_with_stdio(0);
    //freopen("d:\\1.txt","r",stdin);
    lon casenum;
    //cin>>casenum;
    //cout<<casenum<<endl;
    //for(lon time=1;time<=casenum;++time)
    //for(lon time=1;cin>>m>>n;++time)
    {
        init();
        work();
        release();
    }
    return 0;
}

 

posted @ 2019-05-20 15:22  degvx  阅读(176)  评论(0)    收藏  举报