877E

来源:互联网 发布:楚楚街聊天是什么软件 编辑:程序博客网 时间:2024/06/14 18:12

877E - Danil and a Part-time Job
给一颗树,结点有权值,更新子树所有结点,查询结点子树的和;


思路参考我上一篇文章

转换完之后就是区间更新和查询,然后更新sum就是把开关的房间调换一下;
更新add值就用对2取余,不能用异或~~(刚开始想着用异或1,后来发现,add的值会超过1)
代码(
注意main() 函数里    A[L[i]]=a; 调试了无数次才发现是这里的问题

因为把结点按照DFS序重新编号后,L[i]才是线段树维护序列的下标;

#include <iostream>#include <cstdio>#include <vector>#include<cstring>#define mem(x) memset(x,0,sizeof(x))#define ls l,m,rt<<1#define rs m+1,r,rt<<1|1using namespace std;const int N=200010;vector<int> G[N];int sum[N<<2],L[N],R[N],A[N],add[N<<2];int fa[N];int vv=0;void init(int n){    for(int i=1;i<N;i++)        G[i].clear();    mem(sum);    mem(L);    mem(R);    mem(add);    mem(fa);    vv=0;}void dfs(int u){    vv++;    L[u]=vv;    for(int i=0;i<G[u].size();i++)    {        int v=G[u][i];        if(v!=fa[u])dfs(v);    }    R[u]=vv;}void pu(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void pd(int rt,int ln,int rn){    if(add[rt]){        add[rt<<1]=(add[rt]+add[rt<<1])%2;        add[rt<<1|1]=(add[rt]+add[rt<<1|1])%2;        //cout<<"add[3]="<<add[3]<<endl;        //cout<<"add[rt]="<<add[rt]<<endl;        //cout<<"add[rt|1]="<<add[rt<<1|1]<<endl;        //cout<<"pd-add-->";for(int i=1;i<=7;i++)cout<<add[i]<<' ';cout<<endl;        //if((rt<<1|1)==3){cout<<add[rt]<<' '<<add[rt<<1|1]<<' '<<(add[rt]+add[rt<<1|1])%2<<endl;}        sum[rt<<1]=ln-sum[rt<<1];        sum[rt<<1|1]=rn-sum[rt<<1|1];        add[rt]=0;    }}void build(int l,int r,int rt){    if(l==r)    {        sum[rt]=A[l];        return ;    }    int m=(l+r)>>1;    build(ls);build(rs);    pu(rt);}void update(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R)    {        sum[rt]=(r-l+1)-sum[rt];        add[rt]=(add[rt]+1)%2;        return ;    }    int m=(l+r)>>1;    pd(rt,m-l+1,r-m);    if(L<=m)update(L,R,ls);    if(R>m)update(L,R,rs);    pu(rt);}int query(int L,int R,int l,int r,int rt){    //cout<<"add-->";for(int i=1;i<=20;i++)cout<<add[i]<<' ';cout<<endl;    //cout<<"sum-->";for(int i=1;i<=20;i++)cout<<sum[i]<<' ';cout<<endl;    if(L<=l&&r<=R)    {        return sum[rt];    }    int m=(l+r)>>1;    pd(rt,m-l+1,r-m);    int ans=0;    if(L<=m)ans+=query(L,R,ls);    if(R>m)ans+=query(L,R,rs);    pu(rt);    return ans;}int main(){    int n,m;    while(~scanf("%d",&n))    {        int a;        init(n);        for(int i=2;i<=n;i++)        {            scanf("%d",&a);            fa[i]=a;            //G[i].push_back(a);            G[a].push_back(i);        }        dfs(1);        for(int i=1;i<=n;i++)        {            scanf("%d",&a);            A[L[i]]=a;        }        //cout<<"L[2]="<<L[2]<<' '<<"R[2]"<<R[2]<<endl;        build(1,n,1);        scanf("%d",&m);        char op[8];int x;        for(int i=1;i<=m;i++)        {            scanf("%s%d",op,&x);            if(op[0]=='g')cout<<query(L[x],R[x],1,n,1)<<endl;            else update(L[x],R[x],1,n,1);        }    }    return 0;}


原创粉丝点击