P4338-[ZJOI2018]历史【LCT】
正題
題目鏈接:https://www.luogu.com.cn/problem/P4338
題目大意
給出nnn個點(diǎn)的一棵樹,和每個點(diǎn)進(jìn)行accessaccessaccess的次數(shù)aia_iai?,要求安排一個順序使得虛實(shí)邊轉(zhuǎn)換最多。
mmm次修改一個點(diǎn)讓aia_iai?加上www后求答案
n,m∈[1,4?105],ai,w∈[1,107]n,m\in [1,4*10^5],a_i,w\in[1,10^7]n,m∈[1,4?105],ai?,w∈[1,107]
解題思路
好像本來就很麻煩還帶修改,那先不考慮修改
考慮統(tǒng)計(jì)每個節(jié)點(diǎn)下的邊的虛實(shí)切換最大化,可以發(fā)現(xiàn)一個節(jié)點(diǎn)的子樹中無論怎樣安排accessaccessaccess順序也不會影響外面的答案,因?yàn)閷τ谕饷娴膩碚f都相當(dāng)于accessaccessaccess了這個節(jié)點(diǎn)。
所以這個滿足子最優(yōu)?(好像是這么叫的),那每一個節(jié)點(diǎn)的分塊考慮就好了。現(xiàn)在對于這個節(jié)點(diǎn)下的邊,如果兩次accessaccessaccess的是在不同的兒子的子樹中就會產(chǎn)生一點(diǎn)貢獻(xiàn)。
轉(zhuǎn)換一下現(xiàn)在的問題就是有若干種個數(shù)不同的顏色排成一排,要求相鄰的異色最多。這個可以貪心解決,正常來說只要每次拿與上個不同的最多的來排就能到達(dá)sum?1sum-1sum?1的答案上線,但是需要特判一下如果最多的顏色個數(shù)mxmxmx有2×mx>sum2\times mx>sum2×mx>sum那么此時這樣排到最后還有一種顏色剩下,答案就是2×(sum?mx)2\times (sum-mx)2×(sum?mx)。
所以一個節(jié)點(diǎn)的答案就是min{sum?1,2×(sum?mx)}min\{sum-1,2\times (sum-mx)\}min{sum?1,2×(sum?mx)}
但是帶修改怎么搞,考慮到每次修改一定是加一個正權(quán)。
我們顯然有一個式子
2×mx>sum?2×(mx+c)>sum+c2\times mx> sum\Rightarrow 2\times (mx+c)> sum+c2×mx>sum?2×(mx+c)>sum+c
這個式子表明如果一個節(jié)點(diǎn)選擇了2×(sum?mx)2\times (sum-mx)2×(sum?mx)作為權(quán)值,那么它以后也都是這個權(quán)值。
sxs_xsx?表示xxx子樹中的權(quán)值和,對一個節(jié)點(diǎn)xxx定義r=max{sy(fay=x)}r=max\{s_y(fa_y=x)\}r=max{sy?(fay?=x)}和sum=∑fay=xsysum=\sum_{fa_y=x}s_ysum=∑fay?=x?sy?
如果2×mx>sum2\times mx>sum2×mx>sum那么向(x,y)(x,y)(x,y)連一條實(shí)邊,其他兒子連虛邊。否則全連虛邊。
那么每次修改的過程中我們只需要遍歷到根節(jié)點(diǎn)的虛邊看是否需要切換即可,這個可以用LCTLCTLCT來維護(hù)。
而且因?yàn)槊織l虛邊代表著2×sy≤sx2\times s_y\leq s_x2×sy?≤sx?,所以路徑上虛邊的個數(shù)不會超過log?∑ai\log \sum a_ilog∑ai?級別。
時間復(fù)雜度O(nlog?∑ai)O(n\log \sum a_i)O(nlog∑ai?)(SplaySplaySplay那個log?n\log nlogn因?yàn)樾∮?span id="ozvdkddzhkzd" class="katex--inline">log?∑ai\log \sum a_ilog∑ai?就舍去)
code
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=4e5+10; struct node{ll to,next; }a[N<<1]; ll n,m,s[N],ls[N],ans,tot; struct LCT{ll fa[N],s[N],w[N],v[N],t[N][2];bool Nroot(ll x){return fa[x]&&(t[fa[x]][0]==x||t[fa[x]][1]==x);}bool Direct(ll x){return t[fa[x]][1]==x;}void PushUp(ll x){s[x]=s[t[x][0]]+s[t[x][1]]+w[x]+v[x];return;}void Rotate(ll x){ll y=fa[x],z=fa[y];ll xs=Direct(x),ys=Direct(y);ll w=t[x][xs^1];t[x][xs^1]=y;t[y][xs]=w;if(Nroot(y))t[z][ys]=x;fa[x]=z;fa[y]=x;if(w)fa[w]=y;PushUp(y);PushUp(x);return;}void Splay(ll x){while(Nroot(x)){ll y=fa[x];if(!Nroot(y))Rotate(x);else if(Direct(x)==Direct(y))Rotate(y),Rotate(x);else Rotate(x),Rotate(x);}return;}ll ct(ll x,ll r,ll h){if(t[x][1])return (r-h)*2;return min(r-1,(r-v[x])*2);}void Access(ll x,ll c){Splay(x);ll r=s[x]-s[t[x][0]],h=s[t[x][1]];ans-=ct(x,r,h);v[x]+=c;r+=c;PushUp(x);if(h*2<r+1)w[x]+=h,t[x][1]=0;ans+=ct(x,r,h);PushUp(x);ll y;for(y=x,x=fa[x];x;y=x,x=fa[x]){Splay(x);ll r=s[x]-s[t[x][0]],h=s[t[x][1]];ans-=ct(x,r,h);w[x]+=c;r+=c;if(h*2<r+1)w[x]+=h,t[x][1]=h=0;if(s[y]*2>r)w[x]-=s[y],t[x][1]=y,h=s[y];ans+=ct(x,r,h);PushUp(x);}return;} }T; void addl(ll x,ll y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return; } void dp(ll x,ll fa){ll son=0,mx=T.v[x]=s[x];T.fa[x]=fa;for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa)continue;dp(y,x);s[x]+=s[y];if(s[y]>mx)son=y,mx=s[y];}ans+=min(s[x]-1,(s[x]-mx)*2);if(mx*2>s[x])T.t[x][1]=son;T.w[x]=s[x]-T.v[x]-s[T.t[x][1]];T.s[x]=s[x];return; } signed main() {scanf("%lld%lld",&n,&m);for(ll i=1;i<=n;i++)scanf("%lld",&s[i]);for(ll i=1;i<n;i++){ll x,y;scanf("%lld%lld",&x,&y);addl(x,y);addl(y,x);}dp(1,0);printf("%lld\n",ans);for(ll i=1;i<=m;i++){ll x,w;scanf("%lld%lld",&x,&w);T.Access(x,w);printf("%lld\n",ans);}return 0; }總結(jié)
以上是生活随笔為你收集整理的P4338-[ZJOI2018]历史【LCT】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 换了手机微信聊天记录怎么恢复换了手机QQ
- 下一篇: AT4505-[AGC029F]Cons