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

前言

有点懊恼的一个题…
并没有其他那些ZJOI那么毒瘤,看出了关键结论,但最后维护卡在log条虚边的伞兵性质上了。

解析

第一眼:感觉根本不可做啊。
冷静一下,既然它还变态的带修,一定是可以转化成比较形式化的东西的。
对每个节点考虑对答案贡献了多少次,设 sxs_xsx 表示 x 子树内权值之和,mxxmx_xmxx 表示 max⁡(ax,max⁡u∈sonxsu)\max(a_x,\max_{u\in son_{x}}s_{u})max(ax,maxusonxsu),那么答案的上界显然是 sx−1s_x-1sx1,但前提是不同子树的权值必须交错出现,因此其实应该是 min⁡(sx−1,2(sx−mxx))\min(s_x-1,2(s_x-mx_x))min(sx1,2(sxmxx)),递归的想可以发现这个结论一直都是对的。写一发暴力得到了30分,说明结论没有问题。

考虑如何快速的维护修改。
一个节点 x 收到某个儿子 son “一家独大”的制约当且仅当 2∗sson≥sx+12*s_{son}\ge s_x+12ssonsx+1。显然至多存在一个这样的儿子,定义其为 hsonxhson_xhsonx(特别的,hsonxhson_xhsonx 可以为 x 自己),(x,hsonx)(x,hson_x)(x,hsonx) 这样的边定义为实边,其他边定义为虚边。
考虑对一个节点 x + w,贡献发生改变的必然是一条返祖链。进一步,发现对于返祖链上的一条实边,其父亲端的贡献必然不会改变。
然后我觉的虚实边变来变去我就不会了。

接下来,通过和树剖类似的证明 ,可以得出任意一条返祖链上的虚边最多有 log⁡ai\log a_ilogai 条。
所以暴力跳修改所有虚边的贡献即可。
实现上,树剖后开两棵线段树,一棵维护虚实边,一棵维护 sxs_xsx 即可。
时间复杂度 O(nlog⁡n(log⁡n+log⁡∑ai))O(n\log n(\log n+\log {\sum a_i}))O(nlogn(logn+logai))

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned ll
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")inline ll read() {ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
const int N=4e5+100;
const int mod=1e9+7;bool mem1;inline ll ksm(ll x,ll k){ll res(1);while(k){if(k&1) res=res*x%mod;x=x*x%mod;k>>=1;}return res;
}int n,m;struct seg{
#define mid ((l+r)>>1)
#define ls (k<<1)
#define rs (k<<1|1)ll sum[N<<2],laz[N<<2];inline void pushup(int k){sum[k]=sum[ls]+sum[rs];}inline void add(int k,int l,int r,ll w){sum[k]+=(r-l+1)*w;laz[k]+=w;}inline void pushdown(int k,int l,int r){ll o=laz[k];laz[k]=0;if(!o) return;add(ls,l,mid,o);add(rs,mid+1,r,o);return;}void change(int k,int l,int r,int x,int y,ll w){if(x<=l&&r<=y){add(k,l,r,w);return;}pushdown(k,l,r);if(x<=mid) change(ls,l,mid,x,y,w);if(y>mid) change(rs,mid+1,r,x,y,w);pushup(k);}int findpre(int k,int l,int r,int p){if(!k) exit(0);//debug("k=%d (%d %d) p=%d\n",k,l,r,p);if(!sum[k]) return 0;if(l==r) return l;if(p<=mid) return findpre(ls,l,mid,p);pushdown(k,l,r);int o=findpre(rs,mid+1,r,p);if(o) return o;else return findpre(ls,l,mid,p);}ll ask(int k,int l,int r,int p){if(l==r) return sum[k];pushdown(k,l,r);if(p<=mid) return ask(ls,l,mid,p);else return ask(rs,mid+1,r,p);}
}t1,t2;
//t1:s
//t2:tagll a[N],s[N],mx[N],ans;
int hson[N],siz[N],top[N],dep[N],fa[N],dfn[N],pos[N],tim;
bool tag[N];
vector<int>e[N];
void dfs1(int x,int f){siz[x]=1;dep[x]=dep[f]+1;fa[x]=f;s[x]=mx[x]=a[x];hson[x]=x;for(int to:e[x]){if(to==f) continue;dfs1(to,x);siz[x]+=siz[to];s[x]+=s[to];if(s[to]>mx[x]){hson[x]=to;mx[x]=s[to];}}ans+=min(s[x]-1,2*(s[x]-mx[x]));ll sh=hson[x]==x?a[x]:s[hson[x]];if(2*sh<s[x]+1) hson[x]=0;if(hson[x]&&hson[x]!=x) tag[hson[x]]=1;return;
}
void dfs2(int x,int tp){//debug("x=%d tp=%d\n",x,tp);top[x]=tp;dfn[++tim]=x;pos[x]=tim;int son=0;for(int to:e[x]){if(to==fa[x]) continue;if(siz[to]>siz[son]) son=to;}if(son) dfs2(son,tp);for(int to:e[x]){if(to==fa[x]||to==son) continue;dfs2(to,to);}return;
}
void init(){  dfs1(1,0);dfs2(1,1);for(int i=1;i<=n;i++){t1.change(1,1,n,pos[i],pos[i],s[i]);if(i>1&&!tag[i]) t2.change(1,1,n,pos[i],pos[i],1);//printf("i=%d hson=%d s=%lld tag=%d\n",i,hson[i],s[i],tag[i]);}return;
}
inline ll calc(ll s,ll mx){return min(s-1,2*(s-mx));
}inline void upd(int x,int w){int ori=x;//printf("upd: x=%d w=%d\n",x,w);if(hson[x]!=x){int son=hson[x];ll sh=son?t1.ask(1,1,n,pos[son]):0,sx=t1.ask(1,1,n,pos[x]);    ans-=calc(sx,sh);ans+=calc(sx+w,max(sh,a[x]+w));//printf("  x=%d son=%d sh=%lld ans=%lld\n",x,son,sh,ans);if(son&&2*sh<(sx+w)+1){t2.change(1,1,n,pos[son],pos[son],1);hson[x]=0;}if(2*(a[x]+w)>(sx+w)+1){hson[x]=x;}}while(x){int p=t2.findpre(1,1,n,pos[x]);if(p==0||p<pos[top[x]]) x=fa[top[x]];else{x=dfn[p];int son=hson[fa[x]];ll sf=t1.ask(1,1,n,pos[fa[x]]),sh=son?son==fa[x]?a[fa[x]]:t1.ask(1,1,n,pos[son]):0,sx=t1.ask(1,1,n,pos[x]);      ans-=calc(sf,sh);ans+=calc(sf+w,max(sx+w,sh));//printf("  x=%d son=%d sf=%lld sh=%lld sx=%lld p=%d ans=%lld\n",x,son,sf,sh,sx,p,ans);if(son&&2*sh<(sf+w)+1){t2.change(1,1,n,pos[son],pos[son],1);hson[fa[x]]=0;}if(2*(sx+w)>=(sf+w)+1){t2.change(1,1,n,pos[x],pos[x],-1);hson[fa[x]]=x;}x=fa[x];}}x=ori;a[x]+=w;while(x){t1.change(1,1,n,pos[top[x]],pos[x],w);x=fa[top[x]];}return;
}bool mem2;
signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();m=read();for(int i=1;i<=n;i++) a[i]=read();for(int i=1;i<n;i++){int x=read(),y=read();e[x].push_back(y);e[y].push_back(x);}init();printf("%lld\n",ans);for(int i=1;i<=m;i++){int x=read(),w=read();upd(x,w);printf("%lld\n",ans);}return 0;
}
/*
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316711.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Named Volume 在 MySQL 数据持久化上的基本应用

原文作者&#xff1a;春哥非常感谢春哥的投稿&#xff0c;同时也有一些感慨。初识春哥时&#xff0c;春哥是美术设计大咖。后不久&#xff0c;创业并致力于游戏开发&#xff0c;已有3年。从Unity3D到IOS&#xff08;Swift&#xff09;开发&#xff0c;从前端开发到后端以及容器…

Codeforces Round #723 (Div. 2)

Codeforces Round #723 (Div. 2) 题号题目知识点AMean Inequality签到BI Hate 1111思维CPotions (Easy Version)思维C1Potions (Hard Version)思维DKill Anton思维逆序对EOolimry and Suffix ArrayFMedian Queries CF1526A Mean Inequality 题意&#xff1a; 给你一个序列a&…

[AtCoder Regular Contest 060] E - Tak and Hotels

AT2039 [ARC060C] 高橋君とホテル / Tak and Hotelsproblemsolution - 分块code - 分块solution - 倍增code - 倍增problem luogu翻译 solution - 分块 肯定刚开始&#xff0c;我们很想暴力跳过去。事件复杂度取决于数据。 肯定不做把头拿给别人砍的事 这种跳法&#xff0…

模板:珂朵莉树

所谓珂朵莉树&#xff0c;就是珂朵莉发明的树。 &#xff08;逃 前言 在数据随机且带区间推平操作时适用&#xff0c;此时所有操作的期望颜色段数都是 O(log⁡n)O(\log n)O(logn) 的&#xff0c;可以使用暴力解决即可。 暴力即优雅。 解析 利用 set 维护颜色段&#xff1a;…

.Netcore 2.0 Ocelot Api网关教程(7)- 限流

本文介绍Ocelot中的限流&#xff0c;限流允许Api网关控制一段时间内特定api的总访问次数。限流的使用非常简单&#xff0c;只需要添加配置即可。1、添加限流修改 configuration.json 配置文件&#xff0c;对 UpstreamPathTemplate 为 /webapib/values 的配置修改如下&#xff1…

cf1526 C Potions

cf1526 C Potions 题意&#xff1a; n个药剂&#xff0c;每个药剂可以加/减能量&#xff0c;一开始能量为0&#xff0c;从左往右开始进行&#xff0c;全程能量不为负&#xff0c;问最多可以使用几个药剂 本题有简单(n<2000),困难模式(n≤200000) 题解&#xff1a; 简单题…

[CF 526 F] Pudding Monsters(单调栈 + 线段树)

CF526F Pudding Monstersproblemsolutioncodeproblem luogu翻译 solution observation &#xff1a;每行每列恰好有一个棋子&#xff0c;所以如果一段区间 [l,r][l,r][l,r] 会被某个 kkk 统计&#xff0c;当且仅当这个区间内棋子纵坐标 ymax−ymin1r−l1y_{max}-y_{min}1r-l…

微信开发必看,使用.Net Core 开发微信跨平台应用

.NET Core 是一个开源通用的开发框架&#xff0c;源码由微软官方和社区共同支持。支持跨平台&#xff0c;即支持在 Window&#xff0c;macOS&#xff0c;Linux 等系统上的开发和部署&#xff0c;并且可以在硬件设备&#xff0c;云服务&#xff0c;和嵌入式/物联网方案中进行使用…

P5590 赛车游戏(差分约束)

前言 9月做的题现在不会了&#xff1f;&#xff1f;&#xff1f; 越学越拉了属于是。 解析 设 disxdis_xdisx​ 表示 1-x 的最小距离&#xff0c;那么一条 u->v 的边的边权就是 disv−disudis_v-dis_udisv​−disu​。 差分约束即可。 挂掉的坑点&#xff1a;只需要考虑…

CF1526 D. Kill Anton

CF1526 D. Kill Anton 题意&#xff1a; 给你一个由’A’,‘N’.‘T’,O’四个字符组成的字符串b&#xff0c;现在要求你改变b的顺序得到a&#xff0c;使得a通过移动回到b的步数最多。 每次移动只能移动相邻两项 题解&#xff1a; 官方题解说&#xff1a;最佳情况为相同字符…

[luogu P4198] 楼房重建(线段树 + 思维)

luogu 楼房重建problemsolutioncodeproblem 洛谷链接 solution 非常巧妙的一道题&#xff0c;对线段树的运用很灵活。 显然这个与原点的连线可以想到将每个点转化为与原点连线形成的直线斜率。 答案其实就是&#xff1a;从第一个点开始选&#xff0c;后一个斜率比前面大的…

模板:P6114 【模板】Lyndon 分解Runs(字符串)

你不会连跑步都不会吧。 &#xff08;逃 前言 SAM&#xff1a;runs&#xff1f;那我run了。 比 SAM 看起来层次更高的奥妙算法。 理论证明比较复杂&#xff0c;但板子写起来都比较简单。 本文会略过很多的证明。 Lyndon 分解 Definition&#xff1a; 如果一个串本身比它的所…

ASP.NET Core 3.0预览版体验

目前.NET Core 3.0的版本为.NET Core 3.0 Preview 3&#xff0c;对应ASP.NET Core 3.0 Preview 3。ASP.NET Core 3.0 之后将不再支持.NET Framework&#xff0c;只运行在.NET Core 上面。ASP.NET Core 3.0 现在已经出到了第三个预览版&#xff0c;增加和改进了很多功能。环境准…

【无码专区13】最小公倍数(线段树)

因为只有std&#xff0c;没有自我实现&#xff0c;所以是无码专区 主要是为了训练思维能力 my idea顾名思义&#xff0c;记录了我的整个思维过程&#xff0c;以及自己部分实现细节口胡&#xff0c;还有期望分数 solution才是dls正解&#xff0c;但是因为只有潦草几句&#x…

2021牛客暑期多校训练营2

2021牛客暑期多校训练营2 题号题目知识点AArithmetic ProgressionBCannonCDraw GridsDEr Ba GameEGas StationFGirlfriendGLeague of LegendsHOlefinIPenguinsbfsJProduct of GCDsKStackLWeChat Walk

P6772 [NOI2020] 美食家(矩阵快速幂)

前言 无能狂怒。 见过甚至写过博客的trick&#xff0c;但就是想不起来了。 解析 做法1 设 ft,xf_{t,x}ft,x​ 表示 t 时刻在 x 的最大价值。 直接转移即可&#xff0c;时间复杂度 O(T(nm))O(T(nm))O(T(nm))&#xff0c;期望得分 40 分。 结合无脑转圈的 A 性质&#xff0c;…

C# .net 中 Timeout 的处理及遇到的问题

C# 中 Timeout 的处理前言最近在项目中要实现一个功能&#xff0c;是关于 Timeout 的&#xff0c;主要是要在要在 TCP 连接建立的时间 和 整个请求完成的时间&#xff0c;在这两个时间层面上&#xff0c;如果超出了设置的时间&#xff0c;就抛出异常&#xff0c;程序中断。研究…

[CodeJam 2019 Round 3] Rancake Pyramid(笛卡尔树)

CodeJam 2019 Round 3 Rancake Pyramidproblemsolutioncodeproblem 神奈子是个很爱打麻将的老婆婆&#xff0c;有一天她把她的麻将放成了 nnn 堆&#xff0c;第 iii 堆的高度为 aia_iai​ 。 因为她很喜欢风&#xff0c;所以她用风吹倒了最左边的 LLL 堆麻将和最右边的 RRR 堆…

Harbour.Space Scholarship Contest 2021-2022 (open for everyone, rated, Div. 1 + Div. 2)

Harbour.Space Scholarship Contest 2021-2022 (open for everyone, rated, Div. 1 Div. 2) 题号题目知识点ADigits Sum签到BReverse String思维CPenalty思维DBackspace逆向思维EPermutation Shift置换群FPairwise ModuloGCommon Divisor GraphHXOR and DistanceIStairs cf15…

模板:全局平衡二叉树

所谓全局平衡二叉树&#xff0c;就是在全局来看都很平衡的二叉树。 &#xff08;逃 前言 这个引言倒是实话&#xff08;雾 可以把一些本来只能用树剖两个 log 做的问题在单log 时间复杂度解决。 修改通常来说只能支持单点修改。 查询解决链上问题或者全局问题更为方便&#x…