codeforces#225-C - Propagating tree-dfs序(奇偶)+线段树
来源:互联网 发布:win7电脑连接网络 编辑:程序博客网 时间:2024/06/13 23:39
http://codeforces.com/problemset/problem/383/C
题意:给一棵树,根为1,根高度为1,
每次操作 两种
1:x,val, 把x节点加val,把其所有儿子-val,把儿子的儿子都+val,反复如此
2:查询某个节点的值
对每次操作,显然就是把该节点的所有子节点中,奇偶性与X相同的+val,不同的则-val,如此反复
我们先跑一遍dfs序,得到dfs序和每个节点深度,然后用dfs序建两颗线段树,一个是只保留深度为奇的节点,一颗只保留深度为偶的节点(其实直接建两个正常的树,只需要在查询的时候,奇数树上返回偶数深度节点值*0,奇数深度节点值*1即可,偶树同理)
那么每次操作,只需要 对 两个线段树 上下标为in【x】到out【X】的节点 分别 +val和 -val即可
最后每次查询。只需要在两棵树分别查询该节点值,最后返回他们的和
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <iostream>#include <queue>#include <map>#include <set>#include <vector>using namespace std; const int N=200005;int tm[200005],dp[N];int who[200005+50];struct tree{int add[4*N] ,vaild[4*N];void build(int l,int r,int i,int kind) // 线段树的建立; { add[i]=0; if(l==r) {if (dp[who[l]]%2==kind){add[i]=tm[who[l]]; vaild[i]=1; }return;} int mid=(l+r)>>1; build(l,mid,i<<1,kind); build(mid+1,r,i<<1|1,kind); } void pushDown(int i, int l, int r)//把i节点的延迟标记传递到左右儿子节点{if(add[i] != 0){int mid = (l + r) >> 1;add[i << 1] += add[i]; add[i << 1 | 1] += add[i]; add[i] = 0;}} void update(int i, int l, int r, int ql, int qr, int val) {if(l > qr || ql > r) return ;if(l >= ql && r <= qr) { add[i] += val;return ;}pushDown(i, l, r); int mid = (l + r) >> 1;update(i << 1, l, mid, ql, qr, val);update(i << 1 | 1, mid + 1, r, ql, qr, val); }int query(int i, int l, int r, int ql, int qr) {if(l > qr || ql > r)return 0;if(l == r && r == qr)return add[i]*vaild[i];pushDown(i, l, r);//同updateint mid =( l + r) >> 1;if (ql<=mid) return query(i << 1, l, mid, ql, qr) ; else return query(i << 1 | 1, mid + 1, r, ql, qr); }};int in[200005+50],out[200005+50],vis[200005+50]; vector<int > mp[200005]; int id=0;void dfs1(int x,int cur){in[x]=++id;vis[x]=1;dp[x]=cur;who[id]=x; //记下本id指向的节点int i;for (i=0;i<mp[x].size();i++){int v=mp[x][i];if (!vis[v]) dfs1(v,cur+1);}out[x]=id;}tree odd,even;int main(){ int n ,i,x,y,m;cin>>n>>m;for (i=1;i<=n;i++)scanf("%d",&tm[i]); for (i=1;i<=n-1;i++){scanf("%d%d",&x,&y);mp[x].push_back(y);mp[y].push_back(x);}dfs1(1,1);odd.build(1,n,1,1);even.build(1,n,1,0); int op,val;for (i=1;i<=m;i++){scanf("%d",&op);if (op==1){scanf("%d%d",&x,&val);if (dp[x]%2){odd.update(1,1,n,in[x],out[x],val);even.update(1,1,n,in[x],out[x],-val);}else{even.update(1,1,n,in[x],out[x],val);odd.update(1,1,n,in[x],out[x],-val);}}else{scanf("%d",&x);printf("%d\n",odd.query(1,1,n,in[x],in[x])+even.query(1,1,n,in[x],in[x]));} /*for (int j=1;j<=n;j++)printf("%d ",odd.query(1,1,n,in[j],in[j])+even.query(1,1,n,in[j],in[j]));printf("*******\n");*/} return 0;}
0 0
- codeforces#225-C - Propagating tree-dfs序(奇偶)+线段树
- Codeforces Round #225 (Div. 1) C-Propagating tree (DFS序+线段树/树状数组)
- CodeForces - 383C Propagating tree(dfs + 线段树)
- CF 383C Propagating tree(dfs序+线段树)
- 【CodeForces】383C Propagating tree 线段树
- Codeforces Round #225 (Div. 1)-C. Propagating tree(线段树)
- Codeforces 383C Propagating tree DFS序+BIT
- CodeForces 384E Propagating tree (dfs序)
- Codeforces Round#225 div.2E Propagating tree 线段树
- Codeforces 383C . Propagating tree【树状数组,dfs】
- CodeForces 383C Propagating tree
- codeforces 383C Propagating tree
- CODEFORCES, 383C,Propagating tree
- Codeforces Round #225 (Div. 2)---E. Propagating tree(时间戳+线段树)
- CF383C Propagating tree【线段树】
- 383C - Propagating tree 线段树加时间戳
- Codeforces 383C Propagating tree(树状数组)
- Codeforces 383C Propagating tree(树状数组)
- Swing学习笔记(杂乱的知识点随手记)
- JAVA多线程——线程的休眠和恢复
- 洛克《人类理解论》
- mybatis中的XML
- java split
- codeforces#225-C - Propagating tree-dfs序(奇偶)+线段树
- 反射浅析
- Spring框架的两个简化XML配置文件的p-namespace和c-namespace
- jQuery 事件注册与实时事件
- javascript 闭包
- 02-线性结构2 Reversing Linked List
- C#求三角形的周长和面积
- Codeforces 545 C Woodcutters(贪心/DP)
- 网上出名IT技术网站整理