BZOJ 3083 遙遠的國度 樹剖 線段樹

2022-05-12 10:05:30 字數 1404 閱讀 4207

傳送門

前兩個操作都比較基礎。對於第三個操作分類討論一下,首先如果當前根不是要操作點的子樹,那麼就無影響,直接查詢操作點的子樹即可。第二種是當前根是操作點的子樹,那就找到當前根到操作點這條鏈的頂端(也就是操作點的兒子,這個兒子為當前根的祖先),然後將這塊連續的\(dfs\)序挖掉,查詢兩邊就行了。找這個點的時候用倍增即可。(暴力往上跳也能過)

#include#include#include#includeusing namespace std;

const int maxn = 100005;

inline int rd()

while(isdigit(ch))

return f?x:-x;

}int n,m,head[maxn],cnt,to[maxn<<1],nxt[maxn<<1],w[maxn],wt[maxn],rt,num,g[maxn][20];

int siz[maxn],fa[maxn],son[maxn],id[maxn],min[maxn<<2],tag[maxn<<2],top[maxn],dep[maxn];

inline int min(int x,int y) }}

void dfs2(int x,int topf)

}void build(int x,int l,int r)

int mid=(l+r)>>1;

build(x<<1,l,mid);build(x<<1|1,mid+1,r);

min[x]=min(min[x<<1],min[x<<1|1]);

}inline void pushdown(int x)

void update(int x,int l,int r,int l,int r,int k)

int mid=(l+r)>>1;if(tag[x]) pushdown(x);

if(l<=mid) update(x<<1,l,mid,l,r,k);

if(mid>1,ret=0x7fffffff;if(tag[x]) pushdown(x);

if(l<=mid) ret=min(ret,query(x<<1,l,mid,l,r));

if(middep[y]) swap(x,y);update(1,1,n,id[x],id[y],k);

}inline int qrange(int x,int y)

return x;

}inline int qson(int x)

int main()

for(int i=1;i<=n;i++) w[i]=rd();rt=rd();

dfs1(rt,0,1);dfs2(rt,rt);build(1,1,n);

while(m--)

if(op==3)

} return 0;

}

BZOJ 3083 遙遠的國度 樹剖

一開始看到有換根操作可是把我嚇了一跳,我還以為要上top tree呢,結果一開題解。心塞 如果除去換根操作的話就是一道裸的樹鏈剖分了,沒什麼難度,但是加上換根操作以後,別怕,其實聯絡查詢的點和現在的根節點只有4種可能 分3種操作 這裡的討論均基於以1為根節點的有根樹討論 1.x rt 直接查詢整個樹...

BZOJ3083 遙遠的國度 樹剖

zcwwzdjn在追殺十分sb的zhx,而zhx逃入了乙個遙遠的國度。當zcwwzdjn準備進入遙遠的國度繼續追殺時,守護神rapid阻攔了zcwwzdjn的去路,他需要zcwwzdjn完成任務後才能進入遙遠的國度繼續追殺。問題是這樣的 遙遠的國度有n個城市,這些城市之間由一些路連線且這些城市構成了...

BZOJ 3083 遙遠的國度 樹鏈剖分

題目大意 給出一顆無根樹,有鏈的修改操作,還有子樹的查詢。除此之外,還有選定這棵樹的乙個點為根。思路 子樹操作,鏈上修改,帶size域的樹鏈剖分就可以搞定。換根肯定不能真的換,出題人要是閒的沒事所有操作都在換根就慘。我們可以畫一張圖模擬下換根。先按照讀入的順序建一顆有根樹,然後觀察當前的根在要詢問的...