正题

P4338


题目大意

有一棵树,告诉你每个点access的次数(带修改),问实链切换的最多次数


解题思路

先考虑离线的做法:

对于点 x,其不同儿子的子树access会使实链切换(对于点 x access 同理),每次都让不同儿子的子树 access,显然可以让答案最大化

但答案不一定是 szx−1sz_x-1szx​−1(最后无法切换),因为如果存在一个儿子 y 满足 szy>szx−szysz_y > sz_x-sz_yszy​>szx​−szy​,即该子树大小大于其他子树大小之和,那么不存在操作使得 y 中的每次access都被切换掉

所以当 szy×2≥szx+1sz_y\times 2\geq sz_x+1szy​×2≥szx​+1 时答案为 (szx−szy)×2(sz_x-sz_y)\times 2(szx​−szy​)×2(最多切换这么多次不同的), 否则为 szx−1sz_x-1szx​−1


然后再考虑在线的做法:

考虑用LCT维护,实边连接满足 szy×2≥szx+1sz_y\times 2\geq sz_x+1szy​×2≥szx​+1 的儿子(不存在则不连)

每次修改可能会修改当前点到根节点的实链,那么只需考虑对该段的影响

对于原来是实边的,显然加了之后仍然满足,不影响,对于原来是虚边的,先减去原来的贡献,然后再考虑连边计算贡献

每经过一次虚边,那么其他儿子的 sz 就必定大于 当前点的 sz,那么sz至少会变大一倍,所以最多经过 log 条虚边

时间复杂度 O(nlogn)O(n\ log\ n)O(n log n)


code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
#define N 400400
ll n,m,x,y,tot,ans,top,a[N],h[N],d[N];
struct rec
{ll to,nx;
}e[N<<1];
void add(ll x,ll y)
{e[++tot].to=y;e[tot].nx=h[x];h[x]=tot;return;
}
struct LCT
{#define ls son[x][0]#define rs son[x][1]ll v[N],ss[N],s[N],fa[N],son[N][2];bool NR(ll x){return fa[x]&&(son[fa[x]][0]==x||son[fa[x]][1]==x);}bool IRS(ll x){return son[fa[x]][1]==x;}void push_up(ll x){s[x]=s[ls]+s[rs]+ss[x]+v[x];return;}void rotate(ll x){ll y=fa[x],z=fa[y],k=IRS(x),g=son[x][!k];if(NR(y))son[z][IRS(y)]=x;if(g)fa[g]=y;fa[x]=z;fa[y]=x;son[x][!k]=y;son[y][k]=g;push_up(y);return;}void Splay(ll x){while(NR(x)){if(NR(fa[x])){if(IRS(x)==IRS(fa[x]))rotate(fa[x]);else rotate(x);}rotate(x);}push_up(x);return;}ll get(ll x){if(rs)return (v[x]+ss[x])*2;else if(v[x]*2>=(s[x]-s[ls])+1)return ss[x]*2;else return (s[x]-s[ls])-1;}void access(ll x,ll z){Splay(x);ans-=get(x);//减去原有贡献v[x]+=z;s[x]+=z;if(rs&&s[rs]*2<s[x]-s[ls]+1){//断去原来的边ss[x]+=s[rs];rs=0;}ans+=get(x);ll y=x;x=fa[x];for(;x;x=fa[y=x]){Splay(x);ans-=get(x);ss[x]+=z;s[x]+=z;if(rs&&s[rs]*2<s[x]-s[ls]+1){ss[x]+=s[rs];rs=0;}if(s[y]*2>=s[x]-s[ls]+1){//连接新的实边rs=y;ss[x]-=s[rs];}ans+=get(x);}return;}
}T;
void dfs(ll x)//初始连边
{ll hs=0;T.v[x]=a[x];for(ll i=h[x];i;i=e[i].nx){ll y=e[i].to;if(y==T.fa[x])continue;T.fa[y]=x;dfs(y);T.ss[x]+=T.s[y];if(T.s[y]>T.s[hs])hs=y;}T.s[x]=T.v[x]+T.ss[x];if(T.s[hs]*2>=T.s[x]+1){T.son[x][1]=hs;T.ss[x]-=T.s[hs];ans+=(T.v[x]+T.ss[x])*2;}else if(T.v[x]*2>=T.s[x]+1){ans+=T.ss[x]*2;}else ans+=T.s[x]-1;return;
}
int main()
{scanf("%lld%lld",&n,&m);for(ll i=1;i<=n;++i)scanf("%lld",&a[i]);for(ll i=1;i<n;++i){scanf("%lld%lld",&x,&y);add(x,y);add(y,x);}dfs(1);printf("%lld\n",ans);while(m--){scanf("%lld%lld",&x,&y);T.access(x,y);printf("%lld\n",ans);}return 0;
}

【LCT】历史(P4338)相关推荐

  1. Link-Cut Tree

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

  2. 【luogu P4338】【LOJ 2434】历史(LCT)

    历史 题目链接:luogu P4338 / LOJ 2434 题目大意 给你一棵树,其中 1 是根,然后给你每个点的 access 次数,要你规划一个 access 的顺序,使得轻重链的切换次数最大. ...

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

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

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

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

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

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

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

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

  7. P4338-[ZJOI2018]历史【LCT】

    正题 题目链接:https://www.luogu.com.cn/problem/P4338 题目大意 给出nnn个点的一棵树,和每个点进行accessaccessaccess的次数aia_iai​, ...

  8. [Luogu P4338] [BZOJ 5212] [ZJOI 2018] 历史

    洛谷传送门 BZOJ传送门 题目背景 九条可怜是一个热爱阅读的女孩子. 题目描述 这个世界有 nnn 个城市,这 n" role="presentation" style ...

  9. BZOJ5212 ZJOI2018历史(LCT)

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

最新文章

  1. 多版本Python共存时pip给指定版本的python安装package的方法
  2. 相似图片检测:感知哈希算法之dHash的Python实现
  3. ofbiz mysql 中文安装_ofbiz的部署及安装问题解决办法
  4. 时序分析:Kalman滤波(状态空间)
  5. SAP 电商云 Spartacus 产品明细页面的 OCC API 是如何被触发的
  6. 协程(Coroutine)与多线程,多进程
  7. Excel导出显示服务器意外,C# 调用Excel 出现服务器出现意外状况. (异常来自 HRESULT:0x80010105 (RPC_E_SERVERFAULT)...
  8. elasticsearch 查看索引_ElasticSearch 索引基本操作
  9. 数据治理项目失败,90%都是被这29条骚操作搞垮的
  10. 用FileMapping跨进程共享数据
  11. linux系统的总父目录,Linux虚拟文件系统-资料路径名的解析(2)-回退父目录
  12. java cms 源码_PublicCMS开源Java系统 v4.0.190312
  13. [python] 基于chardet识别字符编码
  14. 如何在电脑上给视频去水印
  15. Ubuntu安装python步骤
  16. 中国科学院大学计算机复试,被中国科学院北京计算所录取了...(复试经验)
  17. 【编程马拉松】【014-红与黑】
  18. 小区或公寓pppoe通过路由器怎么上网
  19. 一梦江湖网页提交问题服务器错误,一梦江湖4月3日更新内容详情一览
  20. Excel通过身份证号提取出生年月日(生日)/计算截至当前年龄

热门文章

  1. 做流向图_各类型供热暖系统图大全,一饱眼福!
  2. vba cad 获取宏的路径_VBA批量创建文件目录及链接,建议收藏备用
  3. java获取jtable的路径,Java如何在JTable组件中获取选定的单元格?
  4. threejs 加载两个场景_threejs中的三维场景操作
  5. moore 数据集_警报数据集(alarm dataset)_机器学习_科研数据集
  6. [C++STL]stack容器用法介绍
  7. Balanced Lineup POJ - 3264(线段树模板+查询比大小+建树)
  8. 安卓listview下拉刷新_安卓QQ内测教学,保证不让你走弯路
  9. 常用加密算法(Java实现)总结
  10. P4900 食堂(数学式子推导)