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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【ZJOI2018】历史【结论】【LCT思想】

發布時間:2023/12/3 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【ZJOI2018】历史【结论】【LCT思想】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題意:一棵nnn個點的樹,每個點有權值aia_iai?,初始時給定。維護:

  • 單點權值加上一個正數。

  • 詢問每個點恰好執行aia_iai?次 access 操作,任意安排順序的條件下切換輕重鏈總次數的最大值。

  • n≤4×105n\leq 4\times 10^5n4×105

    一道奇怪的題(?)

    對于一個點uuu,考慮它子樹內兩個相鄰 access的點,它們在uuu這里切換了一次當且僅當它們屬于 不同的 uuu的兒子 為根 的 子樹。(為了方便,我們把uuu單獨這一個點看成uuu的子樹。)

    把來自同一個子樹內的一次access看成一種顏色的小球,我們希望相鄰的不同色小球盡量多。

    結論 設總小球數為nnn,顏色最多的小球個數為mmm,那么最大貢獻為min?{n?1,2(n?m)}\min\{n-1,2(n-m)\}min{n?1,2(n?m)}

    證明

    考慮把最多的顏色擺出來,在m?1m-1m?1個空隙中放其他顏色。

  • 假設最多的顏色只有一種
  • 把所有其他顏色的球依次往空隙中放,放完一個顏色繼續往下一個空隙放,空隙放完了再從第一個開始。

    如果空隙都放完了,即n?m≥m?1n-m\geq m-1n?mm?1,即n?1≤2(n?m)n-1\leq2(n-m)n?12(n?m),所有相鄰的小球顏色都不同,答案為n?1n-1n?1

    否則顏色最多的球一定會相鄰。考慮開始時貢獻為000,插入一個任意顏色的球最多讓貢獻+2+2+2,上面的構造方法可以達到這個最大值,所以最大貢獻為2(n?m)2(n-m)2(n?m)

  • 最多的顏色有多種
  • 顯然這時m≤n2m\leq \frac{n}{2}m2n?,把最多的顏色各取一個構成一組綁在一起,然后其他顏色用同樣的方法放在組之間的空隙內,這樣不會有同色相鄰。

    就可以O(n)O(n)O(n)處理了


    然后考慮怎么用數據結構維護這玩意

    上面已經推過了,雖然表達式看起來很奇怪,但實際上本質上是判斷最大的子樹是否超過自己的一半(這里的大小都是指aaa的和)

    一點也不自然地想到實鏈剖分

    具體而言,設sumusum_usumu?表示uuu子樹內權值和,對于uuu和它的兒子vvv,如果2sumv>sumu+12sum_v>sum_u+12sumv?>sumu?+1(先不管uuu本身什么的),那么vvvuuu的重兒子,顯然重兒子最多有一個。如果不存在這樣的兒子就沒有重兒子。

    這樣做的好處是重鏈上都是取的min?{n?1,2(n?m)}\min\{n-1,2(n-m)\}min{n?1,2(n?m)}的右邊這項,而把父親和兒子加上同一個正數時左邊會變大,右邊不會變,而右邊本來就比左邊小,不僅仍然是重邊,連這個點的答案都不會改變,直接跳過去就可以了。而到根的輕邊是O(log?V)O(\log V)O(logV)的,直接討論一下輕邊的情況即可。

    具體而言就是魔改一下LCT的access,跳輕邊的時候需要判一下。具體實現的時候很詭異,建議直接看代碼。

    注意復雜度是通過輕邊條數而非finger-search保證的,所以必須在修改前dfs一遍處理出重兒子

    復雜度應該是O(nlog?nlog?V)O(n\log n\log V)O(nlognlogV)

    #include <iostream> #include <cstdio> #include <cstring> #include <cctype> #include <vector> #define MAXN 400005 using namespace std; typedef long long ll; inline int read() {int ans=0;char c=getchar();while (!isdigit(c)) c=getchar();while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();return ans; } int ch[MAXN][2],fa[MAXN]; ll val[MAXN],lz[MAXN]; inline void pushlzy(int x,ll v){val[x]+=v,lz[x]+=v;} inline void pushdown(int x) {if (lz[x]){if (ch[x][0]) pushlzy(ch[x][0],lz[x]);if (ch[x][1]) pushlzy(ch[x][1],lz[x]);lz[x]=0;} } inline int get(int x){return ch[fa[x]][1]==x;} inline bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} inline void rotate(int x) {int y=fa[x],z=fa[y];int l=get(x),r=l^1;int w=ch[x][r];if (!isroot(y)) ch[z][get(y)]=x;ch[x][r]=y,ch[y][l]=w;if (w) fa[w]=y;fa[y]=x,fa[x]=z; } int q[MAXN],tp; inline void splay(int x) {q[tp=1]=x;for (int i=x;!isroot(i);i=fa[i]) q[++tp]=fa[i];for (int i=tp;i>=1;i--) pushdown(q[i]);while (!isroot(x)){int y=fa[x];if (!isroot(y)){if (get(x)==get(y)) rotate(y);else rotate(x);}rotate(x);} } ll res[MAXN],a[MAXN],ans; inline int findrt(int x){while (ch[x][0]) pushdown(x),x=ch[x][0];return x;} inline void access(int x,int v) {a[x]+=v;for (int y=0;x;y=x,x=fa[x]){splay(x);val[x]+=v;if (ch[x][0]) pushlzy(ch[x][0],v);ans-=res[x];int t=findrt(ch[x][1]);if (2*(val[x]-val[t])>=val[x]-1) ch[x][1]=0;t=findrt(y);if (2*(val[x]-val[t])<val[x]-1) ch[x][1]=y;t=findrt(ch[x][1]);res[x]=(t? 2*(val[x]-val[t]):val[x]-1);if (2*a[x]>val[x]+1) res[x]=2*(val[x]-a[x]);ans+=res[x];} } vector<int> e[MAXN]; void dfs(int u) {val[u]=a[u];for (int i=0;i<(int)e[u].size();i++)if (e[u][i]!=fa[u]){fa[e[u][i]]=u;dfs(e[u][i]);val[u]+=val[e[u][i]];}for (int i=0;i<(int)e[u].size();i++)if (e[u][i]!=fa[u]&&2*val[e[u][i]]>val[u]+1)ch[u][1]=e[u][i];res[u]=(ch[u][1]? 2*(val[u]-val[ch[u][1]]):val[u]-1);if (2*a[u]>val[u]+1) res[u]=2*(val[u]-a[u]);ans+=res[u]; } int main() {int n,m;n=read(),m=read();for (int i=1;i<=n;i++) a[i]=read();for (int i=1;i<n;i++){int u,v;u=read(),v=read();e[u].push_back(v),e[v].push_back(u);}dfs(1); printf("%lld\n",ans);while (m--){int x,v;x=read(),v=read();access(x,v);printf("%lld\n",ans);}return 0; }

    總結

    以上是生活随笔為你收集整理的【ZJOI2018】历史【结论】【LCT思想】的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。