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

2021-08-14 02:37:50 字數 1455 閱讀 8351

題目傳送門

最近心真的有點浮躁啊……連題目都不想好好看了……於是就把「一條樹枝其實就是乙個從某個節點到根的路徑的一段」看成了「一條樹枝其實就是乙個從某個節點到根的路徑」……wqnmlgb……

操作1的k≤

5 ,那麼是不是會想到容斥?對兩條路徑求交?

但是分析一下時間複雜度,o(

m×log22n

×2k)

,接近20億啊……搞毛啊……

考慮給每一條路徑打上標記,最後求樹上所有被標記的點的權值和即可。打標記可以用另乙個線段樹來實現。

結果發現容斥比後一種方法還要快……woc……

附上ac**:

#include 

#include

#include

#include

using

namespace

std;

const

int n=2e5+10,mod=(1ll<<31)-1;

struct sides[n<<1];

int n,x,y,h[n],num,m,cnt,o;

int d[n],f[n],top[n],sz[n],wz[n],size,hs[n];

int t[n<<2],w[n<<2],lz[n<<2],tag[n<<2];

inline

char nc(void)

inline

void read(int &a)

inline

void add(int x,int y),h[x]=num;

s[++num]=(side),h[y]=num;

}inline

void so1(int x,int fa)

return;

}inline

void so2(int x,int fa)

#define lt (k<<1)

#define rt (k<<1|1)

#define mid (l+r>>1)

inline

void push(int k,int l,int r)

if (~tag[k])

return;

}inline

void updata(int k)

inline

void change(int k,int l,int r,int ql,int qr,int v)

inline

void cover(int k,int l,int r,int ql,int qr,int v)

inline

void work(int x,int y)

if (d[x]>d[y]) swap(x,y);

return cover(1,1,n,wz[x],wz[y],1);

}int main(void)}}

return

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 這棵樹長出了一些果子,即某個子樹中的每個節點都會長...

BZOJ3589 動態樹 樹鏈剖分 線段樹

別忘了這是一棵動態樹,每時每刻都是動態的.小明要求你在這棵樹上維護兩種事件 事件0 這棵樹長出了一些果子,即某個子樹中的每個節點都會長出k個果子.事件1 小明希望你求出幾條樹枝上的果子數.一條樹枝其實就是乙個從某個節點到根的路徑的一段.每次小明會選定一些樹枝,讓你求出在這些樹枝上的節點的果子數的和....