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;}
阅读全文
0 0
- 877E
- e
- E
- E
- e
- e
- e
- e
- e
- E
- e
- E
- e
- e
- E
- e
- e
- e
- C++中几种读取数据的函数的用法
- MPAndroidChart开源图表库的使用介绍之饼状图、折线图和柱状图
- 操作系统进程调度算法(Java 实现)
- Webpack 3.x 尝试使用Pug(Jade)模板引擎
- 数理逻辑在程序中的应用
- 877E
- Python简化类例四:关于规范化写法的建议
- Quartzt框架与Spring整合使用详解
- Unity绘制抛物线
- ECO生态币官网blog.sina.com.cn/ecocoin
- (OK) Install php 5.6 in fedora-27
- [1126]codeforces灌水总结
- unique_distance
- 疯狂啃的C