BZOJ3083 遙遠的國度(樹鏈剖分 線段樹)

2022-05-20 18:40:21 字數 1840 閱讀 5377

考慮暴力樹剖。那麼修改路徑和查詢子樹最小值非常簡單。

對於換根當然不能真的給他轉一下,我們只記錄當前根是哪個。對於查詢,如果查詢點不在當前根到原根的路徑上,顯然換根是對答案沒有影響的;如果是當前根,答案就是整棵樹最小值,否則即是要查詢該路徑上的後代所在子樹外的點的最小值,去掉這段區間就可以了。

#include#include

#include

#include

#include

#include

using

namespace

std;

#define n 100010

#define int unsigned int

#define inf 2147483649

intread()

while (c>='

0'&&c<='

9') x=(x<<1)+(x<<3)+(c^48),c=getchar();

return x*f;

}int n,m,root,p[n],a[n],t=0,cnt=0

;int

dfn[n],id[n],fa[n],son[n],deep[n],size[n],top[n];

int l[n<<2],r[n<<2],tree[n<<2],lazy[n<<2

];struct dataedge[n

<<1

];void addedge(int x,int y)

void dfs1(intk)}

void dfs2(int k,int

from

)void build(int k,int l,int

r)

int mid=l+r>>1

; build(k

<<1

,l,mid);

build(k

<<1|1,mid+1

,r);

tree[k]=min(tree[k<<1],tree[k<<1|1

]);}

void down(int

k)void up(int k)

int query(int k,int l,int

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

x)

if(lazy[k]) down(k);

int mid=l[k]+r[k]>>1

;

if (r<=mid) modify(k<<1

,l,r,x);

else

if (l>mid) modify(k<<1|1

,l,r,x);

else modify(k<<1,l,mid,x),modify(k<<1|1,mid+1

,r,x);

up(k);

}void jump_modify(int x,int y,int

z)

if (deep[x]modify(

1,id[y],id[x],z);

}int getans(int

k)

if (deep[x]if (k==y)

else

return query(1,id[k],id[k]+size[k]-1);}

signed main()

for (int i=1;i<=n;i++) a[i]=read();

dfs1(1);

dfs2(

1,1);

build(

1,1,n);

root=read();

while (m--)

}return0;

}

bzoj3083 遙遠的國度

題意 給定一棵樹,支援換根,路徑權值覆蓋,求子樹最小。思路 求子樹?上樹鏈剖分,但是換根怎麼辦?我們只能通過原有資訊推出換根後的答案。換根不影響路徑修改,所以只要考慮子樹最小值的維護。這裡要分3種情況討論 1 如果詢問點是當前根,直接返回整棵樹的最小值。2 如果在原樹中,當前根不在 x的子樹中,直接...

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...