bzoj2819: Nim

这岂不是一眼树剖??

WTF怎么R了。discuss不是说不会爆吗。。

妈也手写栈?

WTF怎么WA了,mdzz数组, WTF怎么MLE了。。

蛤,还能TLE?我去还卡常。。。OKOK

就是沙茶题啊

但是他给我展示了各种报错的魅力

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

int n;

struct node
{
    int x,y,next;
}a[1100000];int len,last[510000];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}

/*
void pre_tree_node(int x)
{
    son[x]=0;tot[x]=0;
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(fa[x]!=y)
        {
            fa[y]=x;
            dep[y]=dep[x]+1;
            pre_tree_node(y);
            if(tot[son[x]]<tot[y])son[x]=y;
            tot[x]+=tot[y];
        }
    }
}
void pre_tree_edge(int x,int tp)
{
    ys[x]=++z;tp[x]=tp;
    if(son[x]!=0)pre_tree_edge(son[x],tp);
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(fa[x]!=y&&son[x]!=y)
            pre_tree_edge(y,y);
    }
}
dfs版*/

int top,sta[1100000],cur[510000];//cur表示当前点枚举到那一条边 

int dep[510000],tot[510000],fa[510000],son[510000];
void pre_tree_node()  
{
    for(int i=1;i<=n;i++)cur[i]=last[i];
    
    top=0;sta[++top]=1;
    tot[1]=1;dep[1]=1;
    while(top!=0)
    {
        int x=sta[top];
        int k=cur[x];
        if(a[k].y==fa[x])k=cur[x]=a[cur[x]].next;
        
        if(k!=0)
        {
            int y=a[k].y;
            sta[++top]=y;
            tot[y]=1;dep[y]=dep[x]+1;fa[y]=x;
            cur[x]=a[k].next;
        }
        else//该点的子节点已访问完毕,回溯 
        {
            top--;  
            if(fa[x]!=0)
            {
                tot[fa[x]]+=tot[x];
                if(tot[son[fa[x]]]<tot[x])son[fa[x]]=x;  
            }
        }
    }
}
int z,ys[510000],tp[510000];
bool v[510000];
void pre_tree_edge()
{
    for(int i=1;i<=n;i++)cur[i]=last[i];
    memset(v,false,sizeof(v));
    
    top=0;sta[++top]=1;
    ys[1]=++z;tp[1]=1;
    while(top!=0)
    {  
        int x=sta[top];  
        if(v[x]==false)//先访问重儿子 
        {  
            v[x]=true;
            if(son[x]!=0)
            {
                sta[++top]=son[x];
                ys[son[x]]=++z;tp[son[x]]=tp[x];
            }
        }
        else
        {
            int k=cur[x];
            if(a[k].y==fa[x]||a[k].y==son[x])k=cur[x]=a[cur[x]].next;
            if(a[k].y==fa[x]||a[k].y==son[x])k=cur[x]=a[cur[x]].next;
            if(k!=0)
            {
                int y=a[k].y;
                sta[++top]=y;
                ys[y]=++z;tp[y]=y;
                cur[x]=a[k].next;
            }
            else top--;
        }
    }
}
//手写栈,非递归版 

//---------composition----------------

struct seqtree
{
    int l,r,lc,rc,c;
}tr[1100000];int trlen;
int gb[1100000];
void bt(int l,int r)
{
    trlen++;int now=trlen;
    tr[now].l=l;tr[now].r=r;
    if(l==r)
    {
        tr[now].lc=tr[now].rc=-1;
        tr[now].c=gb[l];
    }
    else
    {
        int mid=(l+r)/2;
        tr[now].lc=trlen+1;bt(l,mid);
        tr[now].rc=trlen+1;bt(mid+1,r);
        tr[now].c=(tr[tr[now].lc].c^tr[tr[now].rc].c);
    }
}

//--------init tree-----------

void change(int now,int p,int c)
{
    if(tr[now].l==tr[now].r){tr[now].c=c;return ;}
    int mid=(tr[now].l+tr[now].r)/2;
    int lc=tr[now].lc,rc=tr[now].rc;
    if(p<=mid)change(lc,p,c);
    else       change(rc,p,c);
    tr[now].c=(tr[lc].c^tr[rc].c);
}
int getyh(int now,int l,int r)
{
    if(tr[now].l==l&&tr[now].r==r)return tr[now].c;
    int mid=(tr[now].l+tr[now].r)/2;
    int lc=tr[now].lc,rc=tr[now].rc;
           if(r<=mid)return getyh(lc,l,r);
    else if(mid+1<=l)return getyh(rc,l,r);
    else return (getyh(lc,l,mid)^getyh(rc,mid+1,r));
    
}
int solve(int x,int y)
{
    int tx=tp[x],ty=tp[y];
    int ans=0;
    while(tx!=ty)
    {
        if(dep[tx]>dep[ty]) swap(x,y), swap(tx,ty);
        ans^=getyh(1,ys[ty],ys[y]);
        y=fa[ty];ty=tp[y];
    }
    if(dep[x]>dep[y])swap(x,y);
    ans^=getyh(1,ys[x],ys[y]);
    
    if(ans!=0)return 1;
    else       return 0;
}

int stone[510000];
char ss[10];
int main()
{
    
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&stone[i]);
    
    int x,y;
    len=0;memset(last,0,sizeof(last));
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        ins(x,y);ins(y,x);
    }
    
    pre_tree_node();
    pre_tree_edge();
    for(int i=1;i<=n;i++)gb[ys[i]]=stone[i];
    bt(1,n);trlen=0;
    
    int m=0;
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%s%d%d",ss+1,&x,&y);
        if(ss[1]=='Q')
        {
            if(solve(x,y)==1)printf("Yes\n");
            else              printf("No\n");
        }
        else 
        {
            stone[x]=y;
            change(1,ys[x],stone[x]);
        }
    }
    return 0;
}

 

posted @ 2018-03-01 18:54  AKCqhzdy  阅读(199)  评论(0编辑  收藏  举报