bzoj3720 Gty的妹子樹 樹分塊

2021-08-17 03:13:53 字數 1871 閱讀 5436

【題目鏈結】

【題解】

按dfs序樹分塊的模板題。

每個節點的子樹在dfs序中一定為一串連續的區間,那我們對dfs序分塊就行了,每個塊內元素按大小排序。查詢時暴力找邊界上的塊,中間的塊二分一下。修改時暴力維護大小順序,插入時插在它的父親後(dfs序為它的父親+1),然後暴力修改當前塊的dfs序。

複雜度o(n

n−−√

logn

) o(n

nlog

n)

可以修改塊的大小使複雜度更優。

/* --------------

user vanisher

problem bzoj-3720

----------------*/

# include # define ll long long

# define inf 0x3f3f3f3f

# define n 60010

# define k 1001

using namespace std;

int read()

while (ch>='0'&&ch<='9')

return tmp*fh;

}struct edgee[n*2];

struct nodek[k][k];

int w[n],nex[k],n,t,now,kdep[k],num,size[k],dep[n],nowdep,p[n],dad[n],head[n],place;

bool cmpw(node x, node y)

void dfs(int x, int fa)

k[num][++now]=; p[x]=num; dad[x]=fa;

dep[x]=dep[fa]+1, nowdep=min(dep[x],nowdep);

for (int ed=head[x]; ed!=0; ed=e[ed].next)

if (e[ed].data!=fa)

dfs(e[ed].data,x);

}int query(int x, int y)

ans=ans+size[ed]+1-now;

} l=1, r=size[ed];

for (int i=1; i<=size[ed]; i++)

if (dep[k[ed][i].id]<=dep[x])

r=min(r,k[ed][i].p-1);

for (int i=1; i<=size[ed]; i++)

if (k[ed][i].p>=l&&k[ed][i].p<=r)

if (w[k[ed][i].id]>y) ans++;

return ans;

}void modify(int x, int y)

} void cut(int x)

sort(k[x]+1,k[x]+size[x]+1,cmpw);

sort(k[num]+1,k[num]+size[num]+1,cmpw);

}void extend(int x, int y); p[n]=p[x];

for (int j=size[p[x]]-1; j>0&&w[k[p[x]][j].id]>w[k[p[x]][j+1].id]; j--)

swap(k[p[x]][j],k[p[x]][j+1]);

if (size[p[x]]>=2

*t) cut(p[x]);

return;

}}int main()

if (opt==1) modify(x,w);

if (opt==2) extend(x,w);

}return

0;}

bzoj3720 Gty的妹子樹

我們可以樹上分塊,詳見我部落格中雜文下的根號演算法題庫 然後每個塊維護降序,對於整一塊在子樹內的就可以二分,其餘部分暴力。include include include include define fo i,a,b for i a i b i using namespace std const i...

BZOJ3720 Gty的妹子樹

如果沒有插入操作,那麼直接對dfs序建立線段樹套平衡樹即可,有插入操作的話,將外層的線段樹換成重量平衡樹即可。一開始寫替罪羊樹套權值線段樹無限mle 所以只好寫替罪羊樹套treap include include includeusing namespace std typedef unsigned...

BZOJ3720 Gty的妹子樹

題目 題解 傳說中的塊狀樹。和鏈剖思想差不多,能塞到父親塊裡的就塞,否則自己新開一塊。只是比較糾結樹分塊究竟用什麼?如果是樹上莫隊的話好像不能這麼分?被菊花卡死?然後我們就每個塊暴力維護資訊。剛開始以為set就行了,到了寫查詢的時候發現尼瑪set是不能維護名次的t t 還是老老實實寫線性表吧。塊開s...