傳送門
這是一道好題啊……沒有換根的話就是樹剖板子題,但是加上換根怎麼辦?
每次暴力重構dfs序?那不t死你……(突然想到自己動態點分治每次重新跑一遍點分治的sd思路)
那麼我們肯定是老套路,尋找修改根結點之後的不變數。我們先以最開始給定的根,來確定dfs序和其他一切一切的樹剖基本工作。
把路徑全部修改成乙個權值沒什麼難度,主要是看換根之後的訪問問題。
我們分三種情況討論:
1.根結點就是當前訪問的點。
這種情況非常好解決,直接輸出整體最小值即可。
2.根結點不在當前訪問的節點的子樹內。
這個也很容易,因為根結點如果不在當前訪問的子樹內,那麼這個點的子樹原來是什麼樣現在還是什麼樣,沒什麼變化,直接訪問即可。
3.根結點在當前訪問的子樹內。
這個稍微複雜,不過仔細思考之後發現,那就是這個點當前的子樹,應該是整棵樹減去當然根結點所在的子樹。
好像最穩定的方法是使用倍增求出來哪乙個兒子是root所在的子樹的根,之後訪問其他的即可。不過我沒有採取這種方式,而是用了一種更加暴力的方法:因為樹剖保證了每棵子樹內的dfs序一定是連續的,所以我們去掉這一段,直接訪問剩下兩端的最小值即可。怎麼確定呢?我們列舉每乙個子樹,因為dfs序是連續的,所以如果root的dfs序在dfn[x] ~ dfn[x] + size[x] - 1之內,那麼它就在這個子樹之內。
這個方法其實挺不穩定的,很容易被菊花圖卡……不過其實跑的還挺快……
看一下**。
#include#include#include
#include
#include
#include
#include
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')
using
namespace
std;
typedef
long
long
ll;const
int m = 100005
;const
int inf = 1000000009
;int
read()
while(ch >= '
0' && ch <= '9'
)
return ans *op;
}struct
edge
e[m<<1
];struct
segt[m
<<2
];int
n,m,u,v,root,op,x,y,head[m],hson[m],size[m],dep[m],dfn[m],ecnt,fa[m],top[m],idx,def[m],rk[m];
intnl,nr;
void add(int x,int
y)void dfs1(int x,int f,int
depth)
}void dfs2(int x,intt)}
void build(int p,int l,int
r)
int mid = (l+r) >> 1
; build(p
<<1,l,mid),build(p<<1|1,mid+1
,r);
t[p].v = min(t[p<<1].v,t[p<<1|1
].v);
}void pushdown(int p,int l,int
r)void modify(int p,int l,int r,int kl,int kr,int
val)
int mid = (l+r) >> 1
;
if(t[p].lazy) pushdown(p,l,r);
if(kr <= mid) modify(p<<1
,l,mid,kl,kr,val);
else
if(kl > mid) modify(p<<1|1,mid+1
,r,kl,kr,val);
else modify(p<<1,l,mid,kl,mid,val),modify(p<<1|1,mid+1,r,mid+1
,kr,val);
t[p].v = min(t[p<<1].v,t[p<<1|1
].v);
}int query(int p,int l,int r,int kl,int
kr)int lca(int x,int y,bool flag,int
val)
if(dep[x] >dep[y]) swap(x,y);
if(flag) modify(1,1
,n,dfn[x],dfn[y],val);
returnx;}
void findson(int
x) }
}int
main()}}
return0;
}
3083 遙遠的國度
傳送門 感覺今天浪費了好多時間寫水題 主要傳達的思想是換跟操作不一定要真的換,查詢的時候討論一下查詢點與目前根的關係即可 1 achen 2 include3 include4 include5 include6 include7 include8 include9 include 10 inclu...
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準備進入遙遠的...