BZOJ3589 動態樹 樹鏈剖分 線段樹

2022-08-05 05:57:11 字數 1423 閱讀 5916

別忘了這是一棵動態樹, 每時每刻都是動態的. 小明要求你在這棵樹上維護兩種事件

事件0:

這棵樹長出了一些果子, 即某個子樹中的每個節點都會長出k個果子.

事件1:

小明希望你求出幾條樹枝上的果子數. 一條樹枝其實就是乙個從某個節點到根的路徑的一段. 每次小明會選定一些樹枝, 讓你求出在這些樹枝上的節點的果子數的和. 注意, 樹枝之間可能會重合, 這時重合的部分的節點的果子只要算一次.

第一行乙個整數n(1<=n<=200,000), 即節點數.

接下來n-1行, 每行兩個數字u, v. 表示果子u和果子v之間有一條直接的邊. 節點從1開始編號.

在接下來乙個整數nq(1<=nq<=200,000), 表示事件.

最後nq行, 每行開頭要麼是0, 要麼是1.

如果是0, 表示這個事件是事件0. 這行接下來的2個整數u, delta表示以u為根的子樹中的每個節點長出了delta個果子.

如果是1, 表示這個事件是事件1. 這行接下來乙個整數k(1<=k<=5), 表示這次詢問涉及k個樹枝. 接下來k對整數u_k, v_k, 每個樹枝從節點u_k到節點v_k. 由於果子數可能非常多, 請輸出這個數模2^31的結果.

對於每個事件1, 輸出詢問的果子數.

51 2

2 32 4

1 53

0 1 1

0 2 3

1 2 3 1 1 4

1 <= n <= 200,000, 1 <= nq <= 200,000, k = 5.

生成每個樹枝的過程是這樣的:先在樹中隨機找乙個節點, 然後在這個節點到根的路徑上隨機選乙個節點, 這兩個節點就作為樹枝的兩端.

這題為啥要容斥啊,不就一線段樹+樹剖題嗎。(不過bit的log*32確實比樹剖的倆log*5快)

寫完之後居然沒調就過了樣例???(逃

#include #define mid ((s[x].l+s[x].r)>>1)

using namespace std;

struct segs[2000005];

int n,x,y,op,m,z,i,fa[400005],dep[400005],top[400005],son[400005],siz[400005],id[400005];

vectore[400005];

int dfs1(int x)

return siz[x]=tot+1;

}void dfs2(int x,int fa)

void solve(int x,int y)

int main()

for(scanf("%d",&z);z--;) scanf("%d%d",&x,&y),solve(x,y);

printf("%d\n",s[1].val&0x7fffffff);update(1,1,n,0,0);

}}

樹鏈剖分 BZOJ3589 動態樹

time limit 30 sec memory limit 1024 mb submit 543 solved 193 submit status discuss 別忘了這是一棵動態樹,每時每刻都是動態的.小明要求你在這棵樹上維護兩種事件 事件0 這棵樹長出了一些果子,即某個子樹中的每個節點都會長...

bzoj 3589 動態樹 (樹鏈剖分 線段樹)

time limit 30 sec memory limit 1024 mb submit 451 solved 155 submit status discuss 別忘了這是一棵動態樹,每時每刻都是動態的.小明要求你在這棵樹上維護兩種事件 事件0 這棵樹長出了一些果子,即某個子樹中的每個節點都會長...

BZOJ 3589 動態樹 樹鏈剖分 線段樹

題目傳送門 最近心真的有點浮躁啊 連題目都不想好好看了 於是就把 一條樹枝其實就是乙個從某個節點到根的路徑的一段 看成了 一條樹枝其實就是乙個從某個節點到根的路徑 wqnmlgb 操作1的k 5 那麼是不是會想到容斥?對兩條路徑求交?但是分析一下時間複雜度,o m log22n 2k 接近20億啊 ...