bzoj3083 遙遠的國度

2021-07-03 10:20:45 字數 1827 閱讀 1572

題意:給定一棵樹,支援換根,路徑權值覆蓋,求子樹最小。

思路:求子樹?上樹鏈剖分,但是換根怎麼辦?我們只能通過原有資訊推出換根後的答案。換根不影響路徑修改,所以只要考慮子樹最小值的維護。

這裡要分3種情況討論

1:如果詢問點是當前根,直接返回整棵樹的最小值。

2:如果在原樹中,

當前根不在

x的子樹中,直接返回原樹中x的子樹最小值。判斷x在不在y的子樹中,只要通過dfs序即可,如果x的dfs序大於y,且小於等於y子樹中最後乙個點的dfs序,那麼x就在y的子樹中。

3:如果在原樹中,

當前根在

x的子樹中,那麼就相當於去掉當前根所在的x的兒子的子樹的整棵樹(語文沒學好..具體見圖..)

然後這題就解決了。

#include#include#include#define ls (p<<1)

#define rs ((p<<1)|1)

#define mid ((l+r)>>1)

const int maxn=100010,maxm=200010,maxt=maxn<<3;

using namespace std;

int n,m,pre[maxm],now[maxn],son[maxm],col[maxn],tot,root;

int fa[maxn],hson[maxn],w[maxn],top[maxn],dep[maxn],size[maxn],t,q,z[maxn],cnt,def[maxn],a[maxn],op,last[maxn];

void add(int a,int b)

struct tree

void down(int p)

void build(int p,int l,int r)

build(ls,l,mid),build(rs,mid+1,r);

update(p);

} void change(int p,int l,int r,int a,int b,int v)

down(p);

if (b<=mid) change(ls,l,mid,a,b,v);

else if (a>mid) change(rs,mid+1,r,a,b,v);

else change(ls,l,mid,a,mid,v),change(rs,mid+1,r,mid+1,b,v);

update(p);

} int query(int p,int l,int r,int a,int b)

down(p);

if (b<=mid) return query(ls,l,mid,a,b);

else if (a>mid) return query(rs,mid+1,r,a,b);

else return min(query(ls,l,mid,a,mid),query(rs,mid+1,r,mid+1,b));

}}seg;

void dfs(int x)

}void btree(int x,int tp)

bool in(int root,int a)

void cover(int a,int b,int v)

void answer(int x)

}int main(){

// freopen("country.in","r",stdin);freopen("country.out","w",stdout);

scanf("%d%d",&n,&q);

for (int i=1,a,b;i

bzoj3083 遙遠的國度

time limit 10 sec memory limit 1280 mb submit 1733 solved 429 submit status discuss description 描述 zcwwzdjn在追殺十分sb的zhx,而zhx逃入了乙個遙遠的國度。當zcwwzdjn準備進入遙遠的...

bzoj3083 遙遠的國度

time limit 10 sec memory limit 1280 mb submit 1960 solved 484 submit status discuss 描述zcwwzdjn在追殺十分sb的zhx,而zhx逃入了乙個遙遠的國度。當zcwwzdjn準備進入遙遠的國度繼續追殺時,守護神ra...

Bzoj3083 遙遠的國度

給定一棵有根樹,支援3種操作 1.把首都修改為id 2.將p1 p2路徑上的所有城市的防禦值修改為v 3.詢問以城市id為根的子樹中的最小防禦值。畫了一堆圖之後終於搞懂了一點點,首先換根的話肯定不是真的換。對於每次詢問,設現在的根為root,準備詢問的結點為x。來考慮幾種情況。1.root x 詢問...