CodeForces 276E - Little Girl and Problem on Trees 区间更新..N+1个线段树
来源:互联网 发布:hbo直播软件 编辑:程序博客网 时间:2024/04/19 13:48
注意题目设定..除了根节点1外...其他的点至多两个度..而每个非点必须要有一个父亲..所以每个非根节点至多一个孩子..说明题目所给的树一定是这样的:
对于一个点的上下范围更新...有两种情况发生...一个是在所在的线段内更新...一个是上界超过了线段...更新到其他的线段上去...
对于N个线段..可以用N个线段树来维护其区间更新...但是对于跨过1点更新到其他线段的情况..若每次一条一条的更新..绝对超市..这是用一颗特殊的线段树来维护从1出发到多深..加了多少的值...
为了能方便的维护这颗特别的线段树...当其他的线段会更新到点1时...要做更新范围的调整..比如:
要在2号点更新距离为3的..那么更新范围是红色标出的部分...把这个部分分解为为黄色和红色的部分分别处理..红色就是在这个线段是做区间更新..黄色是在点1记录的距离上区间更新...
由于N+1颗线段树的长度是未知的..所以用vector来开...因为vector是动态申请空间的..并且可以通过下标直接访问元素...
Program:
#include<iostream>#include<stack>#include<queue>#include<stdio.h>#include<algorithm>#include<string.h>#include<cmath>#define ll long long#define oo 1000000007#define MAXN 100004using namespace std; struct node{ int Tn,g; }P[MAXN];vector<int> T[MAXN],col[MAXN],t0; int n,num,M[MAXN];void dfs(int x,int m,int f,int t){ P[x].Tn=m,P[x].g=t; col[num].push_back(0); for (int i=0;i<T[x].size();i++) if (T[x][i]!=f) dfs(T[x][i],m,x,t+1); if (t>M[0]) M[0]=t; return;}void PushDown(int M,int len,int now){ if (!col[M][now]) return; col[M][now<<1]+=col[M][now]; col[M][(now<<1)|1]+=col[M][now]; col[M][now]=0; return;}void update(int M,int L,int R,int c,int l,int r,int now) // M用于确定是哪颗树{ if (L<=l && R>=r) { col[M][now]+=c; return; } PushDown(M,r-l+1,now); int mid=(l+r)>>1; if (L<=mid) update(M,L,R,c,l,mid,now<<1); if (R>mid) update(M,L,R,c,mid+1,r,(now<<1)|1); return; }int query(int M,int p,int l,int r,int now) { if (l==r) return col[M][now]; PushDown(M,r-l+1,now); int mid=(l+r)>>1; if (p<=mid) return query(M,p,l,mid,now<<1); if (p>mid) return query(M,p,mid+1,r,(now<<1)|1); }int main(){ int i,q; scanf("%d%d",&n,&q); for (i=1;i<=n;i++) T[i].clear(); for (i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); T[x].push_back(y),T[y].push_back(x); } num=0,P[1].g=0,M[0]=0; for (i=0;i<T[1].size();i++) { col[++num].clear(),col[num].push_back(0); dfs(T[1][i],num,1,1); } col[0].clear(); i=M[0]<<2; while (i--) col[0].push_back(0); for (i=1;i<=num;i++) { int x=col[i].size(); M[i]=x-1,x<<=2; col[i].clear(); while (x--) col[i].push_back(0); } while (q--) { int tp,v,x,d; scanf("%d",&tp); if (!tp) { int l,r,p,t; scanf("%d%d%d",&v,&x,&d); if (P[v].g-d<=0) l=d-P[v].g+1,update(0,0,min(M[0],l-1),x,0,M[0],1); else l=P[v].g-d; if (v==1) continue; r=min(M[P[v].Tn],P[v].g+d); if (r<l) continue; update(P[v].Tn,l,r,x,1,M[P[v].Tn],1); }else { int ans=0; scanf("%d",&v); ans=query(0,P[v].g,0,M[0],1); if (v!=1) ans+=query(P[v].Tn,P[v].g,1,M[P[v].Tn],1); printf("%d\n",ans); } } return 0;}
- CodeForces 276E - Little Girl and Problem on Trees 区间更新..N+1个线段树
- CodeForces 276E Little Girl and Problem on Trees(线段树区间更新)
- codeforces 276E. Little Girl and Problem on Trees (线段树)
- Codeforces 276E(Little Girl and Problem on Trees)
- Codeforces 276E Little Girl and Problem on Trees【线段树+Bfs序+Dfs序】好题!
- Codeforces Round #169 (Div. 2) E.Little Girl and Problem on Trees(成段更新)
- CF 276E Little Girl and Problem on Trees
- E. Little Girl and Problem on Trees 树状数组 + 线段树
- Codeforces Round #169 (Div. 2) 276E Little Girl and Problem on Trees
- CodeForces 276E Little Girl and Problem on Trees 树状数组
- 【Codeforces Round 169 (Div 2) E】【数据结构区间维护】Little Girl and Problem on Trees 大菊花树的距离性修改查询
- Codeforces Round #169 (Div. 2):E - Little Girl and Problem on Trees
- Little Girl and Problem on Trees - CodeForces #169 (Div. 2) E 树状数组
- Codeforces 276C Little Girl and Maximum Sum(线段树的区间更新)
- [CF]276E. Little Girl and Problem on Trees 树状数组
- Codeforces276E:Little Girl and Problem on Trees
- Codeforces 276C Little Girl and Maximum Sum 线段树区间累加
- Codeforces Round #169 (Div. 2) E. Little Girl and Problem on Trees(给出一棵树,对距离某个点d范围之内的所有点+x,查询某个点的值)
- Visual Studio 开发环境中无法浏览页面/无法进行调试
- chromium r197479g版本编译运行
- 网页上显示天气、IP情况
- XMPP——Smack[1]连接、登陆及账户操作
- 哈夫曼树与哈夫曼编码
- CodeForces 276E - Little Girl and Problem on Trees 区间更新..N+1个线段树
- 程序的局部变量 全局变量 动态申请数据分别存储在什么地方?
- Linux检测网络故障以及恢复网络的方法
- html 文本框 显示输入字符
- Visual Assist X 注释报错的解决
- iphone数据存储之-- Core Data的使用(一)
- 【C/C++学习】之十三、虚函数剖析
- XMPP——Smack[2]会话、消息监听、字体表情和聊天窗口控制
- c++ 对象释放