bzoj3252攻略(线段树+dfs序)
3252: 攻略
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 562 Solved: 238
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
4 3 2 1 1
1 2
1 5
2 3
2 4
Sample Output
HINT
对于100%的数据,n<=200000,1<=场景价值<=2^31-1
Source
dfs序+线段树
/* 嗯,需要维护每个点到根的距离。 首先开始的时候选取叶子结点一定比中间节点优。 当选择了一条链的时候,会对哪些点有影响呢? 答案当然是在这条链上的点的子树。把这个点的子树权值减掉这个点的权值就好。 看到子树,想到dfs序。又因为要查询最大值,所以可以想到用线段树实现。 线段树每个节点维护原树每个点到根的距离的最大值和原树每个节点dfs序所对应的点的编号。 每次查询区间最大值,然后删去这条链,每次删的时候更新子树权值(区间减法)。 删除把这个点的权值赋值为0就好。然后往上走,走的时候到某个点权值为0那么就停。 因为如果某个点权值为0,那么他到根的路径上所有点权都为零。恩。 */ #include<iostream> #include<cstdio> #include<cstring>#define N 200007 #define ll long longusing namespace std; ll n,m,ans,cnt,tot; ll head[N],dis[N],fa[N]; ll S[N],pos[N],T[N],a[N]; struct edge{int u,v,net,w; }e[N<<1]; struct tree{ll l,r,mx,pos,flag; }tr[N<<2];namespace seg {void pushup(int k){if(tr[k<<1].mx>tr[k<<1|1].mx) tr[k].mx=tr[k<<1].mx,tr[k].pos=tr[k<<1].pos;else tr[k].mx=tr[k<<1|1].mx,tr[k].pos=tr[k<<1|1].pos;}void pushdown(int k){tr[k<<1].flag+=tr[k].flag;tr[k<<1|1].flag+=tr[k].flag;tr[k<<1].mx+=tr[k].flag;tr[k<<1|1].mx+=tr[k].flag;tr[k].flag=0;}void build(int k,int l,int r){tr[k].l=l;tr[k].r=r;if(l==r) {tr[k].mx=dis[pos[l]],tr[k].pos=pos[l];return;}int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);pushup(k);}void update(int k,int l,int r,int z){if(tr[k].l==l && tr[k].r==r) {tr[k].mx+=z;tr[k].flag+=z;return;}pushdown(k);int mid=tr[k].l+tr[k].r>>1;if(r<=mid) update(k<<1,l,r,z);else if(l>mid) update(k<<1|1,l,r,z);else update(k<<1,l,mid,z),update(k<<1|1,mid+1,r,z);pushup(k);}}using namespace seg;inline void add(int u,int v) {e[++cnt].v=v;e[cnt].net=head[u];head[u]=cnt; }inline ll read() {ll x=0,f=1;char c=getchar();while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f; }void dfs(int u,int last,ll sum) {S[u]=++tot;pos[tot]=u;dis[u]=sum;for(int i=head[u];i;i=e[i].net){int v=e[i].v;if(v==last) continue;fa[v]=u;dfs(v,u,sum+a[v]);}T[u]=tot; }void change(int u) {while(a[u]){update(1,S[u],T[u],-a[u]);a[u]=0;u=fa[u];} }int main() {int x,y;n=read();m=read();for(int i=1;i<=n;i++) a[i]=read();for(int i=1;i<n;i++) {x=read();y=read();add(x,y);add(y,x);}ans=a[1];a[1]=0;dfs(1,0,0);build(1,1,n);while(m--){tree Tr=tr[1];ans+=Tr.mx;change(Tr.pos);}printf("%lld\n",ans);return 0; }
转载于:https://www.cnblogs.com/L-Memory/p/7756865.html
bzoj3252攻略(线段树+dfs序)相关推荐
- bzoj3252攻略(线段树+dfs序)或者(树链剖分+dfs)
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1341 Solved: 642 [Submit][Status][Discuss] ...
- BZOJ_3252_攻略_线段树+dfs序
BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...
- HDU5692(线段树+dfs序)
Snacks Time Limit:5000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Statu ...
- CodeForces - 620E New Year Tree(线段树+dfs序+状态压缩)
题目链接:点击查看 题目大意:给出一棵无向树,每个节点都有一种颜色,接下来时m次操作: 1 x y:将x及其子树染成y的颜色 2 x:查询x及其子树上共有多少种不同的颜色 题目分析:看完这个题的第一反 ...
- HDU - 3974 Assign the task (线段树 + dfs序)
HDU - 3974 题意:有个公司有一些关系,每个人(除了boss)都有且仅有一个上司,这就是一棵树的关系,然后会有一些操作,C i,询问第i个人现在的任务,T x y,把y任务给x, 给x相当于给 ...
- 苹果树(线段树+Dfs序)
1228 苹果树 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在卡卡的房子外面,有一棵苹果树.每年的春天,树上总会结 ...
- Change FZU - 2277(线段树+dfs序)
There is a rooted tree with n nodes, number from 1-n. Root's number is 1.Each node has a value ai. I ...
- Codeforces 877 E Danil and a Part-time Job(线段树+dfs序)
题目地址 题意:给你一棵树,1为根节点,每个节点都有应该状态0或者1,你有两种操作,pow的操作是把该节点以及他的所有子树的每个节点进行自身异或的操作,get就是查询该节点以及他的所有子树的每个节点有 ...
- BZOJ 3779 LCT 线段树 DFS序 坑
hhhh抄了半天lty代码最后T了 对拍也没事.. 药丸 mine #pragma GCC optimize("O3") //By SiriusRen #include < ...
最新文章
- php memcached get,PHP Memcached操作类
- 带你一文看懂 Blockchain + NoSQL数据库
- html5中的h1,HTML5语义 - 产品列表中的h1用法
- 在子视图中获取父视图的控制器
- seq2seq序列到序列模型
- ACM退役帖(青岛赛后再更新)
- selenium爬取淘宝评论信息
- ts类中的private和protected
- 数据分析 - pandas(7)
- CF1153F Serval and Bonus Problem
- TCL双引号 花括号 中括号
- 米4用linux刷机救转,红米Note4免解锁线刷刷机教程_红米Note4免解锁线刷救砖包
- 收藏一个网站可以在线生成带图片的二维码
- 【转】五分钟理解什么是接口
- 四川电信天邑TY1208-Z_强制刷机固件
- python生成器和迭代器
- 强制类型转换运算符的优先级
- 欧几里得+扩展欧几里得+RSA
- 浅析智能网联产业发展与变化趋势
- 微信小程序和python数据交互_记录 python flask 与微信小程序交互