[ZJOI2018]历史

最大化access轻重链的切换次数

考虑一个点的贡献,即它交换重儿子的次数

发现这个次数只和它自己ai以及每个儿子的子树次数和有关。

一个关键的事实是:

我们可以自上而下进行贪心!

我们最大化fa的贡献,发现,对于操作序列,一个儿子子树的操作是一个子序列,不影响这个儿子子树的贡献!

(内部可以任意交换)

等价于:有m=|son|+1种颜色,每种颜色有若干个

排成一列,最大化相邻不相同颜色的次数

设颜色最多的是h,总和为t

则次数=min(t-1,2*(t-h))

证明的话:考虑先放那最多的h个然后插空,对于剩下的p=(t-h)个,如果p<=h-1,那么显然直接插空,贡献2*p个,如果p>h-1,那么一定可以不断来回插空,达到上界t-1

已经可以做不修改的了。

修改:

关键:1.只加w。2.考虑临界情况:2*h>=t+1时候,贡献2*(t-h),否则贡献t-1。3.仅影响到根的链答案

如果一个点可以作为fa的最大值来源,则把这个链变成实链。

发现,修改一个点x时候,往上跳,实链还是实链,并且贡献还是不变的!

所以,只用考虑虚边的影响

发现,每跳一个虚边,所在子树的S*=2,所以最多log∑ai个

修改虚边:

减去原来的贡献,加上新来的贡献,分类讨论

用LCT的access实现跳跃实链

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');} namespace Miracle{
const int N=4e5+;
int n,m;
struct node{
int nxt,to;
}e[*N];
int hd[N],cnt;
ll ans;
void add(int x,int y){
e[++cnt].nxt=hd[x];
e[cnt].to=y;
hd[x]=cnt;
}
struct tr{
int ch[],fa;
ll v,s,si;
void out(){
cout<<" ch0 "<<ch[]<<" ch1 "<<ch[]<<" fa "<<fa<<endl;
cout<<" v "<<v<<" s "<<s<<" si "<<si<<endl;
}
}t[N];
#define ls t[x].ch[0]
#define rs t[x].ch[1]
bool nrt(int x){
return t[t[x].fa].ch[]==x||(t[t[x].fa].ch[]==x);
}
void pushup(int x){
if(x) t[x].s=t[ls].s+t[rs].s+t[x].si+t[x].v;
}
void rotate(int x){
int y=t[x].fa,d=t[y].ch[]==x;
t[t[y].ch[d]=t[x].ch[!d]].fa=y;
if(nrt(y)) t[t[x].fa=t[y].fa].ch[t[t[y].fa].ch[]==y]=x;
else t[x].fa=t[y].fa;
t[t[x].ch[!d]=y].fa=x;
pushup(y);
}
void splay(int x){
while(nrt(x)){
int y=t[x].fa,z=t[y].fa;
if(nrt(y)){
rotate((t[y].ch[]==x)==(t[z].ch[]==y)?y:x);
}
rotate(x);
}
pushup(x);
}
void dfs(int x,int fa){
ll mx=t[x].v;t[x].s=t[x].v;
int p=x;
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fa) continue;
t[y].fa=x;
dfs(y,x);
t[x].s+=t[y].s;
t[x].si+=t[y].s;
if(t[y].s>mx){
mx=t[y].s;p=y;
}
}
if(*mx>=t[x].s+){
if(p!=x) {
rs=p;t[x].si-=t[p].s;
}
}
ans+=min(t[x].s-,*(t[x].s-mx));
} int main(){
int m;
rd(n);rd(m);
for(reg i=;i<=n;++i){
rd(t[i].v);
}
int x,y;
for(reg i=;i<n;++i){
rd(x);rd(y);
add(x,y);add(y,x);
}
dfs(,);
printf("%lld\n",ans);
ll w;
// for(reg i=1;i<=n;++i){
// cout<<i<<" : ";t[i].out();
// }cout<<endl; while(m--){
rd(x);rd(w);
for(reg y=;x;y=x,x=t[x].fa){
splay(x);
ll S=t[x].s-t[ls].s;
// cout<<" x "<<x<<" y "<<y<<" S "<<S<<endl;
ll con=rs?min(S-,*(S-t[rs].s)):min(S-,*(S-t[x].v));
// cout<<" con "<<con<<endl;
ans-=con;
if(!y) {
t[x].v+=w;S+=w;t[x].s+=w;
}else{
t[x].si+=w;S+=w;t[x].s+=w;
}
// cout<<" out ";t[x].out();
if(y){
if(rs){
if(*t[rs].s<S+&&*t[y].s<S+){
ans+=S-;
t[x].si+=t[rs].s;
rs=;
}else if(*t[rs].s>*t[y].s){
ans+=*(S-t[rs].s);
}else{
ans+=*(S-t[y].s);
t[x].si+=t[rs].s;
t[x].si-=t[y].s;
rs=y;
}
}else{
if(*t[x].v<S+&&*t[y].s<S+){
ans+=S-;
}else if(*t[x].v>*t[y].s){
ans+=*(S-t[x].v);
}else{
ans+=*(S-t[y].s);
t[x].si-=t[y].s;
rs=y;
}
}
}else{
if(rs){
if(*t[rs].s<S+&&*t[x].v<S+){
ans+=S-;
t[x].si+=t[rs].s;
rs=;
}else if(*t[rs].s>*t[x].v){
ans+=*(S-t[rs].s);
}else{
ans+=*(S-t[x].v);
t[x].si+=t[rs].s;
rs=;
}
}else{
if(*t[x].v<S+&&*t[y].s<S+){
ans+=S-;
}else if(*t[x].v>*t[y].s){
ans+=*(S-t[x].v);
}else{
ans+=*(S-t[y].s);
t[x].si-=t[y].s;
rs=y;
}
}
}
pushup(x);
}
printf("%lld\n",ans);
}
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2019/4/13 19:58:12
*/

1.考虑每个点的贡献!把题意进行转化

2.修改时候,考虑具体影响的部分是哪些。

[ZJOI2018]历史的更多相关文章

  1. 【BZOJ5212】[ZJOI2018]历史(Link-Cut Tree)

    [BZOJ5212][ZJOI2018]历史(Link-Cut Tree) 题面 洛谷 BZOJ 题解 显然实际上就是给定了一棵树和每个点被\(access\)的次数,求解轻重链切换的最大次数. 先考 ...

  2. bzoj 5212: [Zjoi2018]历史

    Description 九条可怜是一个热爱阅读的女孩子. 这段时间,她看了一本非常有趣的小说,这本小说的架空世界引起了她的兴趣. 这个世界有n个城市,这n个城市被恰好n?1条双向道路联通,即任意两个城 ...

  3. Luogu4338 ZJOI2018 历史 LCT、贪心

    传送门 题意:在$N$个点的$LCT$中,最开始每条边的虚实不定,给出每一个点的$access$次数,求一种$access$方案使得每条边的虚实变换次数之和最大,需要支持动态增加某个点的$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. BZOJ5212 ZJOI2018历史(LCT)

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

  7. [BZOJ5212][ZJOI2018]历史

    传送门(洛谷) 人生第一道九条可怜……神仙操作…… 看着题解理解了一个早上才勉强看懂怎么回事…… 简化一下题目就是:已知每一个点access的总次数,求一个顺序使虚实边转化的次数最多 考虑一下,对于x ...

  8. [ZJOI2018]历史(LCT)

    这篇还发了洛谷题解 [Luogu4338] [BZOJ5212] 题解 题意 给出一棵树,给定每一个点的 \(access\) 次数,计算轻重链切换次数的最大值,带修改. 先考虑不带修改怎么做 假设 ...

  9. 【BZOJ5212】[ZJOI2018] 历史(LCT大黑题)

    点此看题面 大致题意: 给定一棵树每个节点\(Access\)的次数,求最大虚实链切换次数,带修改. 什么是\(Access\)? 推荐你先去学一学\(LCT\)吧. 初始化(不带修改的做法) 首先考 ...

随机推荐

  1. YAML配置:mapping values are not allowed here

    在配置Eureka服务器配置文件的时候,出现了mapping values not allowed here的错误,原因是的冒号 ”:“后面没有空格. 原因分析:yml文件中,键值对是以": ...

  2. 报错:ch.qos.logback.core.joran.spi.JoranException

    项目中使用了maven. 1.找到本地仓库,删除ch文件夹 2.对项目执行maven install 3.在更新下项目maven update

  3. java 中的打印流

    package cn.zhou; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.F ...

  4. vue2 mint-ui loadmore(下拉刷新)

    <template> <div class="page-loadmore"> <h1 class="page-title"> ...

  5. debug错误

    Description "opt_design" can fail with error messages similar to the following: opt_design ...

  6. codeforces401C

    Team CodeForces - 401C Now it's time of Olympiads. Vanya and Egor decided to make his own team to ta ...

  7. 实验吧 WEB 头有点大

    看到了良心的提示,http header,之后看到了要求.NET framework 9.9 英国 IE,我想想.NET好像还没有更新到9.9,就无视了这重要的提示. 我就看了一眼题解,发现burps ...

  8. pysphere VMware控制模块的一些函数的说明

    对于虚拟机的操作获得虚拟机对象 当你正常连接了服务器后,你就可以使用以下两种方式来得到虚拟机对象. get_vm_by_path get_vm_by_name 虚拟机路径可以从虚拟机右键信息中的”Ed ...

  9. BZOJ2565最长双回文串——manacher

    题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同).输入长度为n的串S,求S的最长双回文子串T,即可将T分为两 ...

  10. Cetos 7 防火墙设置

    1.关闭防火墙: # systemctl stop firewalld.service 2.开启防火墙: # systemctl start firewalld.service 3.关闭开机启动: # ...