日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ5212 ZJOI2018历史(LCT)

發(fā)布時(shí)間:2024/10/12 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ5212 ZJOI2018历史(LCT) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

  首先相當(dāng)于最大化access的輕重邊交換次數(shù)。

  考慮每個點(diǎn)作為戰(zhàn)場(而不是每個點(diǎn)所代表的國家與其他國家交戰(zhàn))對答案的貢獻(xiàn),顯然每次產(chǎn)生貢獻(xiàn)都是該點(diǎn)的子樹內(nèi)(包括自身)此次access的點(diǎn)與上次access的點(diǎn)在該點(diǎn)不同兒子的子樹內(nèi)。假設(shè)得到了最后的崛起序列,可以發(fā)現(xiàn)相互不包含的子樹的貢獻(xiàn)是相互獨(dú)立的,只是內(nèi)部交換而不交換他們的相對順序,對答案沒有任何影響。

  那么現(xiàn)在只需要考慮最大化某點(diǎn)的貢獻(xiàn),顯然應(yīng)該讓不同兒子的子樹內(nèi)的點(diǎn)盡量交替access。設(shè)各點(diǎn)子樹的Σai為si,那么當(dāng)不存在2sson>si時(shí),該點(diǎn)貢獻(xiàn)為si-1,否則為2(si-max{sson})。于是如果沒有修改,對每個子樹求出s就能計(jì)算答案了。

  接下來考慮怎么修改。顯然修改某點(diǎn)會影響該點(diǎn)到根的路徑上的所有點(diǎn)的貢獻(xiàn)。因?yàn)樨暙I(xiàn)與2sson>si的兒子有特殊的關(guān)系,考慮將其視為preferred child,把子樹根與該兒子的邊設(shè)為重邊,如果不存在或根自身就是最大的就與兒子全部連輕邊。同時(shí)注意到修改只會使某點(diǎn)的ai增加,如果其本來就是preferred child,修改后仍然是,并且可以發(fā)現(xiàn)這不會對答案造成影響;如果不是的話可能會存在輕重邊切換的情況,其自身變?yōu)閜referred child,但無論如何這說明這棵子樹原來的sson不足其父親si的一半,而這顯然只能存在log次。所以用一棵不會動的LCT做一個真正的access就能修改了,可以打個lazy避免維護(hù)子樹。感覺有一堆情況事實(shí)上最后也沒啥要討論的。

  雖然寫了一年但是1A感覺爽爆啊?

#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #include<cassert> using namespace std; #define ll long long #define N 400010 #define lson tree[k].ch[0] #define rson tree[k].ch[1] #define lself tree[tree[k].fa].ch[0] #define rself tree[tree[k].fa].ch[1] char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() {int x=0,f=1;char c=getchar();while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f; } int n,m,p[N],t; ll ans; struct data{int to,nxt; }edge[N<<1]; struct data2{int ch[2],fa;ll x,s,lazy,ans; }tree[N]; void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;} void dfs(int k,int from) {tree[k].s=tree[k].x;ll mx=tree[k].x;for (int i=p[k];i;i=edge[i].nxt)if (edge[i].to!=from){tree[edge[i].to].fa=k;dfs(edge[i].to,k);tree[k].s+=tree[edge[i].to].s;mx=max(mx,tree[edge[i].to].s);}if (2*mx<=tree[k].s) tree[k].ans=tree[k].s-1;else{tree[k].ans+=tree[k].s-mx<<1;for (int i=p[k];i;i=edge[i].nxt)if (edge[i].to!=from&&tree[edge[i].to].s==mx) {tree[k].ch[1]=edge[i].to;break;}}ans+=tree[k].ans; } void add(int k,ll x){if (k) tree[k].s+=x,tree[k].lazy+=x;} void down(int k){if (tree[k].lazy) add(lson,tree[k].lazy),add(rson,tree[k].lazy),tree[k].lazy=0;} int whichson(int k){return rself==k;} bool isroot(int k){return lself!=k&&rself!=k;} void push(int k){if (!isroot(k)) push(tree[k].fa);down(k);} void move(int k) {int fa=tree[k].fa,gf=tree[fa].fa,p=whichson(k);if (!isroot(fa)) tree[gf].ch[whichson(fa)]=k;tree[k].fa=gf;tree[fa].ch[p]=tree[k].ch[!p],tree[tree[k].ch[!p]].fa=fa;tree[k].ch[!p]=fa,tree[fa].fa=k; } void splay(int k) {push(k);while (!isroot(k)){int fa=tree[k].fa;if (!isroot(fa))if (whichson(fa)^whichson(k)) move(k);else move(fa);move(k);} } void access(int k,int x) {tree[k].x+=x;for (int t=0;k;){splay(k);if (rson){int p=rson;for (;tree[p].ch[0];p=tree[p].ch[0]) down(p);splay(p);while (!isroot(k)) move(k);}tree[k].s+=x;ans-=tree[k].ans;if ((tree[rson].s<<1)<=tree[k].s) rson=0;if ((tree[t].s<<1)>tree[k].s) rson=t,tree[k].ans=tree[k].s-tree[t].s<<1;else if ((tree[k].x<<1)>tree[k].s) tree[k].ans=tree[k].s-tree[k].x<<1;else if ((tree[rson].s<<1)>tree[k].s) tree[k].ans=tree[k].s-tree[rson].s<<1;else tree[k].ans=tree[k].s-1;ans+=tree[k].ans;add(lson,x);for (;lson;k=lson) down(k);splay(k);t=k;k=tree[k].fa;} } int main() { #ifndef ONLINE_JUDGEfreopen("bzoj5212.in","r",stdin);freopen("bzoj5212.out","w",stdout);const char LL[]="%I64d\n"; #elseconst char LL[]="%lld\n"; #endifn=read(),m=read();for (int i=1;i<=n;i++) tree[i].x=read();for (int i=1;i<n;i++){int x=read(),y=read();addedge(x,y),addedge(y,x);}dfs(1,1);cout<<ans<<endl; for (int i=1;i<=m;i++){int x=read(),y=read();access(x,y);printf(LL,ans);}return 0; }

?

轉(zhuǎn)載于:https://www.cnblogs.com/Gloid/p/10091951.html

總結(jié)

以上是生活随笔為你收集整理的BZOJ5212 ZJOI2018历史(LCT)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。