time limit: 10 sec memory limit: 1280 mb
submit: 1733 solved: 429
[submit][status][discuss]
description
描述 zcwwzdjn在追殺十分sb的zhx,而zhx逃入了乙個遙遠的國度。當zcwwzdjn準備進入遙遠的國度繼續追殺時,守護神rapid阻攔了zcwwzdjn的去路,他需要zcwwzdjn完成任務後才能進入遙遠的國度繼續追殺。
問題是這樣的:遙遠的國度有n個城市,這些城市之間由一些路連線且這些城市構成了一顆樹。這個國度有乙個首都,我們可以把這個首都看做整棵樹的根,但遙遠的國度比較奇怪,首都是隨時有可能變為另外乙個城市的。遙遠的國度的每個城市有乙個防禦值,有些時候rapid會使得某兩個城市之間的路徑上的所有城市的防禦值都變為某個值。rapid想知道在某個時候,如果把首都看做整棵樹的根的話,那麼以某個城市為根的子樹的所有城市的防禦值最小是多少。由於rapid無法解決這個問題,所以他攔住了zcwwzdjn希望他能幫忙。但zcwwzdjn還要追殺sb的zhx,所以這個重大的問題就被轉交到了你的手上。
input
第1行兩個整數n m,代表城市個數和運算元。
第2行至第n行,每行兩個整數 u v,代表城市u和城市v之間有一條路。
第n+1行,有n個整數,代表所有點的初始防禦值。
第n+2行乙個整數 id,代表初始的首都為id。
第n+3行至第n+m+2行,首先有乙個整數opt,如果opt=1,接下來有乙個整數id,代表把首都修改為id;如果opt=2,接下來有三個整數p1 p2 v,代表將p1 p2路徑上的所有城市的防禦值修改為v;如果opt=3,接下來有乙個整數 id,代表詢問以城市id為根的子樹中的最小防禦值。
output
對於每個opt=3的操作,輸出一行代表對應子樹的最小點權值。
sample input
3 71 2
1 31 2 3
3 12 1 1 6
3 12 2 2 5
3 12 3 3 4
3 1sample output
提示對於20%的資料,n<=1000 m<=1000。
對於另外10%的資料,n<=100000,m<=100000,保證修改為單點修改。
對於另外10%的資料,n<=100000,m<=100000,保證樹為一條鏈。
對於另外10%的資料,n<=100000,m<=100000,沒有修改首都的操作。
對於100%的資料,n<=100000,m<=100000,0《所有權值<=2^31。
題解:這個題主要就是有個換根操作。
假設當前的根式root,要查詢的是以x為子樹的最小值,那麼可以分成三種情況:
①:x==root 那麼就是查詢整棵樹就行了。
②:lca(x,root)!=x 那麼查詢x在原來的樹中的子樹就行了,換根對答案不會有影響。
③:lca(x,root)==x 這種情況就是在查詢的時候扣掉root所在的x的那棵子樹就行了。
其他的就是裸的鏈剖了。
#include
#include
#include
#include
using namespace std;
#define inf 0x7fffffff
const int n=100010;
struct saa[n*2];
int n,m,tot,point[n],next[n*2],a[n],root,fa[n][20];
int deep[n],pos[n],num,belong[n],s[n],tr[n*4],de[n*4],siz[n];
inline int in()
inline void add(int
x,int
y)inline void dfs_1(int
x,int
last)
for(i=point[x];i;i=next[i])
if(aa[i].en!=last)
}inline void dfs_2(int
x,inty)}
inline int lca(int
x,int
y)#define mid (l+r)/2
#define l k<<1,l,mid
#define r k<<1|1,mid+1,r
inline void paint(int k,int z)
inline void pushdown(int k)
inline void insert(int k,int l,int r,int
x,int
y,int z)
if(de[k]) pushdown(k);
if(x
<=mid) insert(l,x,y,z);
if(y>mid) insert(r,x,y,z);
tr[k]=min(tr[k<<1],tr[k<<1|1]);
}inline int query(int k,int l,int r,int
x,int
y)inline void change(int
x,int
y,int z)
insert(1,1,n,pos[y],pos[x],z);
return ;
}inline int get_point(int
x,int
y)int main()
for(i=1;i<=n;++i) a[i]=in();
root=in();
dfs_1(1,0);
dfs_2(1,1);
memset(tr,127,sizeof(tr));
for(i=1;i<=n;++i) insert(1,1,n,pos[i],pos[i],a[i]);
while(m--)
if(t==3)}}
}}
bzoj3083 遙遠的國度
題意 給定一棵樹,支援換根,路徑權值覆蓋,求子樹最小。思路 求子樹?上樹鏈剖分,但是換根怎麼辦?我們只能通過原有資訊推出換根後的答案。換根不影響路徑修改,所以只要考慮子樹最小值的維護。這裡要分3種情況討論 1 如果詢問點是當前根,直接返回整棵樹的最小值。2 如果在原樹中,當前根不在 x的子樹中,直接...
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 詢問...