Description:

给定一棵树,定义每个点的操作为把这个点到1号点的路径覆盖上颜色i,每次该点到1号点经过的不同颜色段数会加到答案中,要使所有点按某一顺序操作完后答案最大
给定每个点要执行的操作次数,并给出m次修改,问每次修改后的最大答案

Hint:

\(n,m \le 4*10^5\)

Solution:

其实主要是要想到这个结论,注意我们可以分别算每个点的答案,再加起来

考虑对于i点的子树,如何让答案更优?

就是要使那些在不同儿子中的点轮流依次操作

实际上有个结论:

如果有一个儿子子树\(size\)小于等于\((sz[i]+1)/2\),则答案就是\(sz[i]-1\)

否则就是\((sz[i]-sz[v])*2\)

这个想想还是很好理解的

于是我们可以把LCT实虚链切换的条件改一下,改成上述

这样每次修改时能方便的维护之前的答案类型

其实这题的LCT只起了一个维持平衡的作用......

代码细节稍多

#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=4e5+5;
int n,m,cnt,hd[mxn];
ll ans;inline int read() {char c=getchar(); int x=0,f=1;while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}return x*f;
}
inline int chkmax(int &x,int y) {if(x<y) x=y;}
inline int chkmin(int &x,int y) {if(x>y) x=y;}struct ed {int to,nxt;
}t[mxn<<1];inline void add(int u,int v) {t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt;
}namespace lct {#define lc(u) (ch[u][0])#define rc(u) (ch[u][1])int fa[mxn],ch[mxn][2]; ll s[mxn],si[mxn],val[mxn];int isnotrt(int x) {return ch[fa[x]][0]==x||ch[fa[x]][1]==x;}void push_up(int x) {s[x]=s[lc(x)]+s[rc(x)]+val[x]+si[x];}void rotate(int x) {int y=fa[x],z=fa[y],tp=ch[y][1]==x;if(isnotrt(y)) ch[z][ch[z][1]==y]=x; fa[x]=z;ch[y][tp]=ch[x][tp^1]; fa[ch[x][tp^1]]=y;ch[x][tp^1]=y; fa[y]=x;push_up(y); push_up(x);}void splay(int x) {while(isnotrt(x)) {int y=fa[x],z=fa[y];if(isnotrt(y))(ch[y][1]==x)^(ch[z][1]==y)?rotate(x):rotate(y);rotate(x);  }}ll cal(int x,ll tp,ll h) {if(rc(x)) return (tp-h)*2; else if(val[x]*2>tp) return (tp-val[x])*2; //重儿子只维护了子节点信息,当前节点需要特判else return tp-1;}void modify(int x,int w) {splay(x); ll tp=s[x]-s[lc(x)],h=s[rc(x)];ans-=cal(x,tp,h); s[x]+=w; val[x]+=w; tp+=w; if(h*2<tp+1) si[x]+=h,rc(x)=0; //只可能是总size变大,故只考虑重->轻ans+=cal(x,tp,h); push_up(x); int y=x; x=fa[x];for(;x;x=fa[y=x]) {splay(x); tp=s[x]-s[lc(x)],h=s[rc(x)];ans-=cal(x,tp,h); s[x]+=w,si[x]+=w,tp+=w;if(h*2<tp+1) si[x]+=h,rc(x)=0,h=0;if(s[y]*2>tp) si[x]-=s[y],rc(x)=y,h=s[y];ans+=cal(x,tp,h); push_up(x);}}void dfs(int u) {s[u]=val[u]; int son=0; ll mx=val[u];//这里一定要考虑自己for(int i=hd[u];i;i=t[i].nxt) {int v=t[i].to;if(v==fa[u]) continue ;fa[v]=u; dfs(v); s[u]+=s[v];if(s[v]>mx) mx=s[son=v];}ans+=min(s[u]-1,(s[u]-mx)*2);if(mx*2>=s[u]+1) rc(u)=son;si[u]=s[u]-val[u]-s[rc(u)];}
}
using namespace lct;int main()
{n=read(); m=read(); int u,v;for(int i=1;i<=n;++i) val[i]=read();for(int i=1;i<n;++i) {u=read(); v=read();add(u,v); add(v,u);}dfs(1); printf("%lld\n",ans);for(int i=1;i<=m;++i) {u=read(); v=read(); modify(u,v); printf("%lld\n",ans);}return 0;
}

转载于:https://www.cnblogs.com/list1/p/10533794.html

[ZJOI2018]历史相关推荐

  1. [LCT动态树] [NOI2014]魔法森林,[ZJOI2018]历史

    [NOI2014] 魔法森林 题目 按照aaa精灵从小到大排序 按顺序插入每一条边 加入第iii条边后的最小代价为a[i]a[i]a[i]加上从111到nnn的所有路径中最大bbb最小的路径代价 维护 ...

  2. Luogu4338 ZJOI2018 历史 LCT、贪心

    传送门 题意:在$N$个点的$LCT$中,最开始每条边的虚实不定,给出每一个点的$access$次数,求一种$access$方案使得每条边的虚实变换次数之和最大,需要支持动态增加某个点的$access ...

  3. P4338 [ZJOI2018]历史 LCT+树形DP

    \(\color{#0066ff}{ 题目描述 }\) 这个世界有 n 个城市,这 n 个城市被恰好 \(n-1\) 条双向道路联通,即任意两个城市都可以 互相到达.同时城市 1 坐落在世界的中心,占 ...

  4. BZOJ5212 ZJOI2018历史(LCT)

    首先相当于最大化access的轻重边交换次数. 考虑每个点作为战场(而不是每个点所代表的国家与其他国家交战)对答案的贡献,显然每次产生贡献都是该点的子树内(包括自身)此次access的点与上次acce ...

  5. [ZJOI2018]历史,洛谷P4338,类LCT维护

    正题 题目大意,大致就是给出一棵有根数,给出每个点access的次数,要你安排顺序,求轻重边切换最多多少次,动态加次数. 第一步其实还挺好想的,思考一下如何静态做,发现相当于对于每一个节点,就是让各个 ...

  6. P4338 [ZJOI2018]历史(树剖)(暴力)

    前言 有点懊恼的一个题- 并没有其他那些ZJOI那么毒瘤,看出了关键结论,但最后维护卡在log条虚边的伞兵性质上了. 解析 第一眼:感觉根本不可做啊. 冷静一下,既然它还变态的带修,一定是可以转化成比 ...

  7. 洛谷P4338 [ZJOI2018]历史(LCT,树形DP,树链剖分)

    洛谷题目传送门 ZJOI的考场上最弱外省选手T2 10分成功滚粗...... 首先要想到30分的结论 说实话Day1前几天刚刚刚掉了SDOI2017的树点涂色,考场上也想到了这一点 想到了又有什么用? ...

  8. Link-Cut Tree

    Link-Cut Tree 概述. LCT是一种支持动态维护树上路径信息的数据结构,其本质是实链剖分,通过其他数据结构维护实链的信息达到维护路径及一些子树信息的效果(通常为splay) 刚开始学的时候 ...

  9. ZJOI2019一轮停课刷题记录

    Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...

最新文章

  1. 部署harbor1.2.0开启ldap验证
  2. Python Django 自定义Manager(重写父类方法实现自定义逻辑)
  3. 3.2Python的循环结构语句:
  4. CodeChef Chef and Churu [分块]
  5. datatables 的导出button自定义
  6. matlab堆栈的思想,[转载]Matlab源代码:堆栈类Stack的实现
  7. cad完全卸载教程_AutoCAD 2019 如何卸载,彻底卸载CAD教程
  8. bzoj 3545: [ONTAK2010]Peaks Kruskal重构树
  9. cesium模型不遮挡点线面_VueCLI3.0干货系列之集成Cesium三维地球框架
  10. 关于origin2019的安装教程
  11. json-server 和mock.js生成大量json数据
  12. Jquery插件ajaxFileUpload文件上传与Bootstrap之fileinput插件上传文件的使用与MultipartFile使用与导入Excel和导出Excel
  13. python推荐系统-Python黑马头条推荐系统项目
  14. 网络空间安全--密码学重点(适合提前自学的宝宝)
  15. C++计算四则表达式的模板
  16. 苹果手机微信记录恢复最简单的恢复方法
  17. 网页设计配色应用实例剖析——黄色系
  18. $this-assign('manualList', $manualList)是什么意思
  19. Apache Ratis中的multi-raft实现原理
  20. 转载:中国动漫:缺失的一代

热门文章

  1. codeception (4)Yii2下创建Acceptance Tests(验收测试)
  2. hibernate和struts2实现分页功能
  3. java 自带thread分析工具_java自带的jvm分析工具
  4. dhcp动态主机配置协议
  5. aspose.cells 无法读取公式值_隐藏 Excel表格、公式的9种方法
  6. 无线传感器网络WSN技术、协议、距离汇总
  7. 腾讯全力支持鸿蒙,腾讯宣布大力发展车联网,或与华为鸿蒙强强联合!
  8. Confluence 6 Home 和其他重要的目录
  9. 开源 | 蚂蚁金服分布式中间件开源第二弹:丰富微服务架构体系
  10. ASP.NET Core的配置(5):配置的同步[设计篇]