題意:一棵n
nn個點的樹,每個點有權值a
ia_i
ai,初始時給定。維護:
單點權值加上乙個正數。
詢問每個點恰好執行a
ia_i
ai次 access 操作,任意安排順序的條件下切換輕重鏈總次數的最大值。
n ≤4
×105
n\leq 4\times 10^5
n≤4×10
5一道奇怪的題(?)
對於乙個點u
uu,考慮它子樹內兩個相鄰 access的點,它們在u
uu這裡切換了一次當且僅當它們屬於 不同的 u
uu的兒子 為根 的 子樹。(為了方便,我們把u
uu單獨這乙個點看成u
uu的子樹。)
把來自同乙個子樹內的一次access看成一種顏色的小球,我們希望相鄰的不同色小球盡量多。
結論設總小球數為n
nn,顏色最多的小球個數為m
mm,那麼最大貢獻為min
\min\
min
證明
考慮把最多的顏色擺出來,在m−1
m-1m−
1個空隙中放其他顏色。
假設最多的顏色只有一種
把所有其他顏色的球依次往空隙中放,放完乙個顏色繼續往下乙個空隙放,空隙放完了再從第乙個開始。
如果空隙都放完了,即n−m
≥m−1
n-m\geq m-1
n−m≥m−
1,即n−1
≤2(n
−m
)n-1\leq2(n-m)
n−1≤2(
n−m)
,所有相鄰的小球顏色都不同,答案為n−1
n-1n−
1 否則顏色最多的球一定會相鄰。考慮開始時貢獻為0
00,插入乙個任意顏色的球最多讓貢獻+2+2
+2,上面的構造方法可以達到這個最大值,所以最大貢獻為2(n
−m
)2(n-m)
2(n−m)
最多的顏色有多種
顯然這時m≤n
2m\leq \frac
m≤2n
,把最多的顏色各取乙個構成一組綁在一起,然後其他顏色用同樣的方法放在組之間的空隙內,這樣不會有同色相鄰。
就可以o(n
)o(n)
o(n)
處理了然後考慮怎麼用資料結構維護這玩意
上面已經推過了,雖然表示式看起來很奇怪,但實際上本質上是判斷最大的子樹是否超過自己的一半(這裡的大小都是指a
aa的和)
一點也不自然地想到實鏈剖分
具體而言,設sum
usum_u
sumu
表示u
uu子樹內權值和,對於u
uu和它的兒子v
vv,如果2su
mv
>su
mu+1
2sum_v>sum_u+1
2sumv
>su
mu+
1(先不管u
uu本身什麼的),那麼v
vv是u
uu的重兒子,顯然重兒子最多有乙個。如果不存在這樣的兒子就沒有重兒子。
這樣做的好處是重鏈上都是取的min
\min\
min的右邊這項,而把父親和兒子加上同乙個正數時左邊會變大,右邊不會變,而右邊本來就比左邊小,不僅仍然是重邊,連這個點的答案都不會改變,直接跳過去就可以了。而到根的輕邊是o
(logv
)o(\log v)
o(lo**
)的,直接討論一下輕邊的情況即可。
具體而言就是魔改一下lct的access,跳輕邊的時候需要判一下。具體實現的時候很詭異,建議直接看**。
注意複雜度是通過輕邊條數而非finger-search保證的,所以必須在修改前dfs一遍處理出重兒子
複雜度應該是o(n
log
nlogv
)o(n\log n\log v)
o(nlog
nlo**)
#include
#include
#include
#include
#include
#define maxn 400005
using
namespace std;
typedef
long
long ll;
inline
intread()
int ch[maxn][2
],fa[maxn]
;ll val[maxn]
,lz[maxn]
;inline
void
pushlzy
(int x,ll v)
inline
void
pushdown
(int x)
}inline
intget
(int x)
inline
bool
isroot
(int x)
inline
void
rotate
(int x)
int q[maxn]
,tp;
inline
void
splay
(int x)
rotate
(x);}}
ll res[maxn]
,a[maxn]
,ans;
inline
intfindrt
(int x)
inline
void
access
(int x,
int v)
}vector<
int> e[maxn]
;void
dfs(
int u)
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];}
intmain()
dfs(1)
;printf
("%lld\n"
,ans)
;while
(m--
)return0;
}
ZJOI2018遊記總結
題解在此,雖然我並沒有看懂 其實省選三天前就結束了,但因為這兩天忙於補作業,並且我覺得這次省選比較有借鑑意義,所以我放到今天才寫。時間回到考試當天,那天早上六點多我們就除了賓館,匆匆填飽了肚子便奔赴考場。題目發下來,t1我看了一眼就感覺是數學題 我數學不好 於是先放下了t1。t2明顯是有暴力分的,所...
ZJOI2018二試遊記
zjoi2018果然比hnoi2018 本菜雞騙了200,分數上肯定比zjoi多 良心多了,一試和二試都是,每次都有幾天聽課。重點是 zjoi有飯吃!上午從學校出發,坐了4個小時來到yy,中午自己解決,晚飯在yyzx的食堂吃了幾個月來最 的飯菜 綠豆湯裡有生的綠豆?想到明天要聽課,於是晚上逛了逛知乎...
餘姚中學ZJOI2018遊記 4 25
今天是集訓的第二天,也是最後一天。早上講了一些國家集訓隊互測的題。我看到ppt的名字 一些毒瘤互測題的解法 就覺得特別的難,果然也是特別的難。有很多數論的不可做題。自己還是太菜了,對於數論的東西基本上沒有了解,什麼莫比烏斯反演,ntt雖然聽過,但我都不會,於是講課的時候聽到這些演算法就 啊哦,聽過 ...