题意:给定一棵树和点的\(Access\)次数,求切换链的最大值。

考虑修改时实边与虚边的贡献,用\(LCT\)维护此树。

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2000010;
const int INF = 0x7fffffff;
#define int long long
inline int read()
{
int q=0,f=1;char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-1;ch=getchar();
}
while(isdigit(ch)){
q=q*10+ch-'0';ch=getchar();
}
return q*f;
}
int head[maxn];
int cnt;
struct edge
{
int nxt;
int to;
}e[maxn<<1];
inline void add(int u,int v){
e[++cnt].to = v;
e[cnt].nxt = head[u];
head[u] = cnt;
return;
} int ans; struct LCT{
int ch[maxn][2];
int fa[maxn];
int stack[maxn];
int val[maxn];
int sum[maxn];
int isum[maxn];
inline bool isroot(int x){
return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
}
inline void push_up(int now){
sum[now] = val[now] + sum[ch[now][0]]+sum[ch[now][1]]+isum[now];
}
inline void rotate(int x){
int f=fa[x];
int ff = fa[f];
int y = (ch[f][0] == x);
bool flag = isroot(f);
fa[x] = ff;
fa[f] = x;
fa[ch[x][y]] = f;
if(!flag) ch[ff][ch[ff][1]==f] = x;
ch[f][!y] = ch[x][y];
ch[x][y] = f;
push_up(f);
}
inline void splay(int x){
while(!isroot(x)){
int f = fa[x];
if(!isroot(f)){
if((ch[fa[f]][0] == f)^(ch[f][0] == x)) rotate(x);
else rotate(f);
}
rotate(x);
}
push_up(x);
}
inline void access(int x,int v,int nt){
for(;x;nt = x,x = fa[x]){
splay(x);
int res = sum[ch[x][1]] + val[x] + isum[x];
if(ch[x][1]){
ans -=((res-sum[ch[x][1]]) << 1);
}
else if(res + 1 <= val[x] * 2){
ans -= 2*(res - val[x]);
}
else ans -= (res - 1);
sum[x] += v;
isum[x] += v;
res += v;
if(res+1 > sum[ch[x][1]]*2){
isum[x] += sum[ch[x][1]];
ch[x][1] = 0;
}
if(res + 1<= sum[nt]*2){
ch[x][1] = nt;
isum[x] -= sum[ch[x][1]];
}
if(ch[x][1]){
ans += 2*(res - sum[ch[x][1]]);
}
else if(res + 1 <= val[x]*2){
ans += 2*(res - val[x]);
}
else ans += (res - 1);
}
}
inline void update(int x,int f){
splay(x);
int res = sum[ch[x][1]] + val[x] + isum[x];
if(ch[x][1]) ans -= 2*(res - sum[ch[x][1]]);
else if(res + 1 <= val[x] * 2){
ans -= 2*(res - val[x]);
}
else ans -= (res - 1);
val[x] += f;
sum[x] += f;
res += f;
if(res + 1 > sum[ch[x][1]] * 2){
isum[x] += sum[ch[x][1]];
ch[x][1] = 0;
}
if(ch[x][1]){
ans += 2*(res - sum[ch[x][1]]);
}
else if(res + 1 <= val[x] * 2){
ans += (res - val[x]) * 2;
}
else ans += (res - 1);
access(fa[x],f,x);
}
inline void dfs(int x,int f){
fa[x] = f;
sum[x] = val[x];
int maxm = val[x];
int i;
int tmp = x;
for(int i = head[x];i;i=e[i].nxt){
int y = e[i].to;
if(y == f) continue;
dfs(y,x);
sum[x] += sum[y];
if(sum[y] > maxm){
tmp = y;
maxm = sum[y];
}
}
ans += min(sum[x]-1,2*(sum[x]-maxm));
if(tmp != x && sum[x] + 1 <= maxm * 2) ch[x][1] = tmp;
isum[x] = sum[x] - val[x] - sum[ch[x][1]];
}
inline void ins(){
dfs(1,0);
}
}lct; signed main()
{
int n = read(),m=read();
for(int i = 1;i <= n; ++i){
lct.val[i] = read();
}
for(int i = 1;i < n; ++i){
int u=read(),v=read();
add(u,v);
add(v,u);
}
lct.ins();
cout<<ans<<endl;
for(int i = 1;i <=m; ++i){
int x = read(),v = read();
lct.update(x,v);
cout<<ans<<endl;
}
return 0; }

[ZJOI 2018]历史的更多相关文章

  1. ZJOI 2018 一试记

    ZJOI一试几天,天微冷,雨.倒是考试当天近午时分出了太阳. 开题前的一刻,心情反而平静了,窗外泛着淡金色的日光照进来,仿佛今天的我并不是所谓来冲击省队,而只是来经历一场洗礼. 开题了,虽然有一点小插 ...

  2. 【ZJOI 2018】 历史(lct)

    历史 题目描述 九条可怜是一个热爱阅读的女孩子. 这个世界有 $n$ 个城市,这 $n$ 个城市被恰好 $n-1$ 条双向道路联通,即任意两个城市都可以互相到达.同时城市 $1$ 坐落在世界的中心,占 ...

  3. 【ZJOI 2018】线图(树的枚举,hash,dp)

    线图 题目描述 九条可怜是一个热爱出题的女孩子. 今天可怜想要出一道和图论相关的题.在一张无向图 $G$ 上,我们可以对它进行一些非常有趣的变换,比如说对偶,又或者说取补.这样的操作往往可以赋予一些传 ...

  4. [ZJOI 2018] 线图

    别想多了我怎么可能会正解呢2333,我只会30分暴力(好像现场拿30分已经不算少了2333,虽然我局的30分不是特别难想). 首先求k次转化的点数显然可以变成求k-1次转化之后的边数,所以我们可以先让 ...

  5. NOIWC前的交流题目汇总

    RT 2018.12.27 i207M:BZOJ 4695 最假女选手 以维护最大值为例,记录最大值和严格次大值和最大值的出现次数,然后取min的时候递归到小于最大值但大于次大值修改,这个就是最重要的 ...

  6. 2018.08.14 bzoj4241: 历史研究(回滚莫队)

    传送们 简单的回滚莫队,调了半天发现排序的时候把m达成了n... 代码: #include<bits/stdc++.h> #define N 100005 #define ll long ...

  7. 【开源】C#.NET股票历史数据采集,【附18年历史数据和源代码】

    如果用知乎,可以关注专栏:.NET开源项目和PowerBI社区 重点重点:我没有买股票,没有买股票,股市是个坑,小心割韭菜哦. 本文的初衷是数据分析(分析结果就不说了,就是想看看筛选点数据),只不过搞 ...

  8. 导航狗IT周报-2018年05月18日

    原文链接:https://www.daohanggou.cn/2018/05/18/it-weekly-8/ DDoS专题 最近Web安全里的一个热点就是包括阮一峰博客在内的多个教育类IT网站被DDo ...

  9. JVM基础系列第2讲:Java 虚拟机的历史

    说起 Java 虚拟机,许多人就会将其与 HotSpot 虚拟机等同看待.但实际上 Java 虚拟机除了 HotSpot 之外,还有 Sun Classic VM.Exact VM.BEA JRock ...

随机推荐

  1. 前端 JavaScript 基础

    内容目录: 一.JavaScript介绍 二.基础语法   2.1 变量   2.2 数据类型   2.3 流程控制   2.5 函数的全局变量和局部变量   2.6 作用域   2.7 词法分析   ...

  2. Linux 进程间通信 有名管道(fifo)

    有名管道特点: 1)无名管道只能用于具有亲缘关系的进程之间,这就限制了无名管道的使用范围 2)有名管道可以使互不相关的两个进程互相通信. 3)有名管道可以通过路径名来指出,并且在文件系统中可见,但内容 ...

  3. Mysql优化-分区

    分区简介 分区是根据一定的规则,数据库把一个表分解成多个更小的.更容易管理的部分.就访问数据库应用而言,逻辑上就只有一个表或者一个索引,但实际上这个表可能有N个物理分区对象组成,每个分区都是一个独立的 ...

  4. WSGI——python-Web框架基础

    1. 简介 WSGI ​ WSGI:web服务器网关接口,这是python中定义的一个网关协议,规定了Web Server如何跟应用程序交互.可以理解为一个web应用的容器,通过它可以启动应用,进而提 ...

  5. Shell test命令(Shell [])详解,附带所有选项及说明

    test 是 Shell 内置命令,用来检测某个条件是否成立.test 通常和 if 语句一起使用,并且大部分 if 语句都依赖 test. test 命令有很多选项,可以进行数值.字符串和文件三个方 ...

  6. 使用Fiddler抓取手机包

    配置Fiddler 设置抓取HTTPS包 允许为外部连接 配置移动端 移动端需要能够连接到主机做代理, 设置移动端的网络, 端口为Fiddler的端口, 然后给移动端安装证书, 访问主机名+代理端口号 ...

  7. [转]Netty入门(最简单的Netty客户端/服务器程序)

    Java中的NIO是一种解决阻塞式IO问题的基本技术,但是NIO的编写对java程序员是有比较高的要求的.那么Netty就是一种简化操作的一个成熟的网络IO编程框架.这里简单介绍一个程序,代码是< ...

  8. leetcode-132-分割回文串②*

    题目描述: 方法一:动态规划 class Solution: def minCut(self, s: str) -> int: min_s = list(range(len(s))) n = l ...

  9. http经典解析

    HTTP访问流程想象用浏览器打开imooc.com网站,HTTP走过的环节: 1.首先,是对imooc.com域名解析, (1.1)浏览器搜索浏览器自身的DNS缓存. (1.2)如果浏览器没有找到自身 ...

  10. 网站数据采集|埋点设计|nginx日志文件

    数据获取的方式主要可以分为两种: 1.网站日志文件(log files) 页面埋点js自定义的采集. 优缺点: web服务器自带的日志记录功能:优点方便,缺点信息收集不全 自定义的js埋点收集:优点想 ...