題目大意:給出一顆無根樹,有鏈的修改操作,還有子樹的查詢。除此之外,還有選定這棵樹的乙個點為根。
思路:子樹操作,鏈上修改,帶size域的樹鏈剖分就可以搞定。換根肯定不能真的換,出題人要是閒的沒事所有操作都在換根就慘。我們可以畫一張圖模擬下換根。先按照讀入的順序建一顆有根樹,然後觀察當前的根在要詢問的點的位置。如果當前的根在要詢問的點的兒子中,那麼那個點為根的時候,當前點的子樹就是除了當前點的有根節點的子樹的點意外的所有點。如果根不在當前點的子樹中,那麼當前點的子樹不變。還有一種情況要特殊討論一下,當前點就是根,那麼子樹就是整棵樹。
ps:乙個點的子樹的範圍是pos[x]~pos[x] + size[x] - 1
code:
#include #include #include #include #define max 100010
#define inf 0x3f3f3f3f
#define left (pos << 1)
#define right (pos << 1|1)
using namespace std;
struct segmenttreetree[max << 2];
int points,asks;
int head[max],total;
int next[max << 1],aim[max << 1];
int deep[max],father[max],size[max],son[max];
int pos[max],top[max],cnt;
int capital;
inline void add(int x,int y)
void predfs(int x,int last)
}void dfs(int x,int last,int _top)
}inline bool insontree(int x,int f)
inline void pushdown(int pos)
}void modify(int l,int r,int x,int y,int pos,int c)
pushdown(pos);
int mid = (l + r) >> 1;
if(y <= mid) modify(l,mid,x,y,left,c);
else if(x > mid) modify(mid + 1,r,x,y,right,c);
else
tree[pos]._min = min(tree[left]._min,tree[right]._min);
}inline void modify(int x,int y,int c)
if(deep[x] < deep[y]) swap(x,y);
modify(1,cnt,pos[y],pos[x],1,c);
}int ask(int l,int r,int x,int y,int pos)
int main()
predfs(1,0);
dfs(1,0,1);
for(int x,i = 1; i <= cnt; ++i)
cin >> capital;
for(int flag,i = 1; i <= asks; ++i)
if(flag == 3)
if(son)
else printf("%d\n",ask(1,cnt,pos[x],pos[x] + size[x] - 1,1));
}} }
return 0;
}
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...