[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. 1228.Poor Pigs 可怜的猪

    转自[LeetCode] Poor Pigs 可怜的猪 There are 1000 buckets, one and only one of them contains poison, the re ...

  2. 剑指offer(11)

    题目: 输入一个链表,输出该链表中倒数第k个结点. 思路: 我们一先想到的应该是循环两次链表,第一次获得它的长度,然后用长度-k,得出目标节点在链表的第几位,再循环一次. 如果要求只用一次循环的话,我 ...

  3. django之路由层

    一 Django中路由的作用 二 简单的路由配置 三 有名分组 四 路由分发 五 反向解析 六 名称空间 七 django2.0版的path 一 Django中路由的作用 URL配置(URLconf) ...

  4. springboot项目小总结

    使用模板引擎 thyemlef 可以直接将 html文件进行导入 loginhtml文件   html中常用的表达式 <link href="asserts/css/signin.cs ...

  5. Storm原理

    zookeeper是对称结构

  6. linux下更改MySQL数据库存储路径

    参考地址:1.https://blog.csdn.net/ArnoBM/article/details/83008212 2.http://www.cnblogs.com/lyongde/p/3725 ...

  7. vue-cli: 渲染过程理解(vue create demo01方式创建)

    1.根目录配置 vue.config.js, 设置入口文件: index.js module.exports = { pages:{ index: { entry: 'src/pages/home/i ...

  8. How to vi

    h:left,j:down,k:up,l:right.wq #write and quitx #cut one letterdd#cut one line/ #searchs/a/b/ #replac ...

  9. JQuery invoke remote webservice

    Sending the Access-Control-Allow-Origin header allows basic cross-origin access, but calling ASP.NET ...

  10. Xamarin + MvvmCross 安装 Part 1

    前言 最近,由于工作需要,公司准备开发移动端APP.临近年底,公司不准备大面招人,由于公司一直基于.net平台进行开发,本人自告奋勇,准备先用xamarin做下移动开发.开始了在网上不停的google ...