线段树
来源:互联网 发布:三维模拟仿真软件 编辑:程序博客网 时间:2024/05/16 02:11
dfs序,对结点进行重编号,要达到的目的是使子树节点的编号都大于父节点,编号完毕后,如果某个节点是非叶子节点,那么它子树节点中的最大值和这个节点的编号代表的区间代表这个子树。编号同时,根节点到此节点(包括此节点)的节点权值和求出,令存数组中。这个新处理出的数组和要求的查询和修改就是(模板的区间求最大值及修改)。过程自行思考。#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<cstdio>#include<cstring>#define lt (2*root)#define rt (2*root+1)#define inf 0x3f3f3f3f3f3f3f3f;using namespace std;typedef __int64 LL;LL a[101000];LL b[101000];LL head[101000],p,book[101000];LL max(LL x,LL y){return x>y?x:y;}struct NOde{ LL Max,mark;}v[401000];struct Node{ int l,r;LL s;//本采用全LL的数据类型,但莫名错误了,求解释?(换下行会WR..) //LL l,r,s; }c[101000];struct Edge{ LL u,v,next;}edges[301000];void build(LL root,LL l,LL r){ if(l==r){v[root].Max=b[l],v[root].mark=0;return;} LL mid=(l+r)/2; build(lt,l,mid); build(rt,mid+1,r); v[root].Max=max(v[lt].Max,v[rt].Max); v[root].mark=0;}void done(LL root,LL value){ v[root].Max=v[root].Max+value; v[lt].mark=v[lt].mark+value; v[rt].mark=v[rt].mark+value;}void push_down(LL root){ if(v[root].mark) { v[root].Max=v[root].Max+v[root].mark; v[lt].mark=v[lt].mark+v[root].mark; v[rt].mark=v[rt].mark+v[root].mark; v[root].mark=0; }}void update(LL root,LL l,LL r,LL from,LL to,LL value){ push_down(root); if(l>to||r<from) return; if(l>=from&&r<=to){done(root,value);return;} LL mid=(l+r)/2; update(lt,l,mid,from,to,value); update(rt,mid+1,r,from,to,value); v[root].Max=max(v[lt].Max,v[rt].Max);}LL query(LL root,LL l,LL r,LL from,LL to){ push_down(root); if(l>to||r<from) return -inf; if(l>=from&&r<=to) return v[root].Max; LL mid=(l+r)/2; return max(query(lt,l,mid,from,to),query(rt,mid+1,r,from,to));}void addedges(LL u,LL v){ edges[p].u=u; edges[p].v=v; edges[p].next=head[u]; head[u]=p++;}LL id=1;void dfs(LL st,LL sum){ c[st].s=sum+a[st]; book[st]=1; c[st].l=id; b[id]=sum+a[st]; for(LL i=head[st];i!=-1;i=edges[i].next) { LL to=edges[i].v; if(book[to]) continue; id=id+1; dfs(to,sum+a[st]); } c[st].r=id; book[st]=0;}void init(LL n){ id=1; dfs(0,0); build(1,1,n);}int main(){ //freopen("C:/Users/hzy/Desktop/12.txt","r",stdin); LL t,kcase=1; scanf("%I64d",&t); while(t--) { memset(head,-1,sizeof(head)); p=0; LL n,m; scanf("%I64d%I64d",&n,&m); for(LL i=0;i<n-1;i++) { LL u,v; scanf("%I64d%I64d",&u,&v); addedges(u,v); addedges(v,u); } for(LL i=0;i<n;i++) scanf("%I64d",&a[i]); printf("Case #%I64d:\n",kcase++); init(n); while(m--) { LL op; scanf("%I64d",&op); if(op==1) { LL pos; scanf("%I64d",&pos); printf("%I64d\n",query(1,1,n,c[pos].l,c[pos].r)); } else { LL pos,value; scanf("%I64d%I64d",&pos,&value); update(1,1,n,c[pos].l,c[pos].r,value-a[pos]); a[pos]=value; } } } return 0;}
阅读全文
0 0
- 线段树?线段树!
- 线段树?线段树!
- 线段_线段树
- 线段_线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- Jsp Model1和Jsp Model2
- java中的包装类与装箱拆箱
- 【数据结构】【并查集模板】
- 网络框架-Volley的使用解析Json以及加载网络图片方法
- Android七种样式dialog
- 线段树
- [ZigBee] 1、 ZigBee简介
- 计蒜客 跳跃游戏2(dp)
- 整除的尾数 oj83
- 算法考题---最小的k个数
- thinkphp 内部函数 D()、F()、S()、C()、L()、A()、I()
- 冒泡排序,选择排序,插入排序
- C++单例模式
- 【密码】 oj85