博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ4712: 洪水(树链剖分维护Dp)
阅读量:4364 次
发布时间:2019-06-07

本文共 3475 字,大约阅读时间需要 11 分钟。

Description

小A走到一个山脚下,准备给自己造一个小屋。这时候,小A的朋友(op,又叫管理员)打开了创造模式,然后飞到
山顶放了格水。于是小A面前出现了一个瀑布。作为平民的小A只好老实巴交地爬山堵水。那么问题来了:我们把这
个瀑布看成是一个n个节点的树,每个节点有权值(爬上去的代价)。小A要选择一些节点,以其权值和作为代价将
这些点删除(堵上),使得根节点与所有叶子结点不连通。问最小代价。不过到这还没结束。小A的朋友觉得这样
子太便宜小A了,于是他还会不断地修改地形,使得某个节点的权值发生变化。不过到这还没结束。小A觉得朋友做
得太绝了,于是放弃了分离所有叶子节点的方案。取而代之的是,每次他只要在某个子树中(和子树之外的点完全
无关)。于是他找到你。

Input

 输入文件第一行包含一个数n,表示树的大小。

接下来一行包含n个数,表示第i个点的权值。
接下来n-1行每行包含两个数fr,to。表示书中有一条边(fr,to)。
接下来一行一个整数,表示操作的个数。
接下来m行每行表示一个操作,若该行第一个数为Q,则表示询问操作,后面跟一个参数x,表示对应子树的根;若
为C,则表示修改操作,后面接两个参数x,to,表示将点x的权值加上to。
n<=200000,保证任意to都为非负数

Output

 对于每次询问操作,输出对应的答案,答案之间用换行隔开。

Sample Input

4
4 3 2 1
1 2
1 3
4 2
4
Q 1
Q 2
C 4 10
Q 1

Sample Output

3
1
4

解题思路:

代码:

1 #include
2 #include
3 #include
4 #define lll spc<<1 5 #define rrr spc<<1|1 6 typedef long long lnt; 7 const int N=200010; 8 struct trnt{ 9 lnt minv; 10 lnt lzt; 11 }tr[N<<2]; 12 struct pnt{ 13 int hd; 14 int fa; 15 int tp; 16 int dp; 17 int wgt; 18 int mxs; 19 int ind; 20 lnt val; 21 lnt f; 22 lnt sigf; 23 }p[N]; 24 struct ent{ 25 int twd; 26 int lst; 27 }e[N<<1]; 28 int cnt; 29 int n,m; 30 int dfn; 31 int plc[N]; 32 char cmd[100]; 33 void ade(int f,int t) 34 { 35 cnt++; 36 e[cnt].twd=t; 37 e[cnt].lst=p[f].hd; 38 p[f].hd=cnt; 39 return ; 40 } 41 void Basic_dfs(int x,int f) 42 { 43 p[x].fa=f; 44 p[x].dp=p[f].dp+1; 45 p[x].wgt=1; 46 int maxs=-1; 47 for(int i=p[x].hd;i;i=e[i].lst) 48 { 49 int to=e[i].twd; 50 if(to==f) 51 continue; 52 Basic_dfs(to,x); 53 p[x].sigf+=p[to].f; 54 p[x].wgt+=p[to].wgt; 55 if(maxs
>1;112 build(l,mid,lll);113 build(mid+1,r,rrr);114 pushup(spc);115 return ;116 }117 void update(int l,int r,int pos,int spc,lnt v)118 {119 if(l==r)120 {121 add(spc,-v);122 return ;123 }124 int mid=(l+r)>>1;125 pushdown(spc);126 if(pos<=mid)127 update(l,mid,pos,lll,v);128 else129 update(mid+1,r,pos,rrr,v);130 pushup(spc);131 return ;132 }133 int scupdate(int l,int r,int ll,int rr,int spc,lnt v)134 {135 if(l>rr||ll>r)136 return 0;137 if(l==r)138 {139 add(spc,v);140 if(tr[spc].minv<=0)141 return plc[l];142 return 0;143 }144 if(ll<=l&&r<=rr&&tr[spc].minv>v)145 {146 add(spc,v);147 return 0;148 }149 int mid=(l+r)>>1;150 pushdown(spc);151 int plcc=scupdate(mid+1,r,ll,rr,rrr,v);152 if(!plcc)153 plcc=scupdate(l,mid,ll,rr,lll,v);154 pushup(spc);155 return plcc;156 }157 lnt query(int l,int r,int pos,int spc)158 {159 if(l==r)160 return tr[spc].minv;161 int mid=(l+r)>>1;162 pushdown(spc);163 if(pos<=mid)164 return query(l,mid,pos,lll);165 return query(mid+1,r,pos,rrr);166 }167 void Update(int x,lnt v)168 {169 if(v<=0||!x)170 return ;171 while(x)172 {173 int tp=scupdate(1,n,p[p[x].tp].ind,p[x].ind,1,v);174 if(!tp)175 x=p[p[x].tp].fa;176 else{177 Update(p[tp].fa,query(1,n,p[tp].ind,1)+v);178 return ;179 }180 }181 }182 int main()183 {184 scanf("%d",&n);185 for(int i=1;i<=n;i++)186 scanf("%d",&p[i].val);187 for(int i=1;i

 

转载于:https://www.cnblogs.com/blog-Dr-J/p/10205803.html

你可能感兴趣的文章
Nutch系列1:简介
查看>>
前端UI框架选择区别对比推荐
查看>>
栈 队列 和 双向队列
查看>>
从垃圾回收看闭包
查看>>
Intel Core Microarchitecture Pipeline
查看>>
如何去除交叉表的子行(列)的小计?
查看>>
Web字体(链接)嵌入
查看>>
switch… case 语句的用法
查看>>
day07补充-数据类型总结及拷贝
查看>>
语言、数据和运算符
查看>>
正则表达式30分钟入门教程
查看>>
sqlserver try catch·
查看>>
1028: 可乐(2018年中南大学研究生复试机试题 )
查看>>
珍藏的最全的windows操作系统快捷键
查看>>
【DBAplus】SQL优化:一篇文章说清楚Oracle Hint的正确使用姿势
查看>>
二叉树结点删除操作
查看>>
图论-单源最短路-SPFA算法
查看>>
转换文件的字符集
查看>>
软件质量理解
查看>>
jquery 在 table 中修改某行值
查看>>