1095: [zjoi2007]hide 捉迷藏
time limit: 40 sec memory limit: 256 mb
submit: 4152 solved: 1756
[submit][status][discuss]
description
捉迷藏 jiajia和wind是一對恩愛的夫妻,並且他們有很多孩子。某天,jiajia、wind和孩子們決定在家裡玩
捉迷藏遊戲。他們的家很大且構造很奇特,由n個屋子和n-1條雙向走廊組成,這n-1條走廊的分布使得任意兩個屋
子都互相可達。遊戲是這樣進行的,孩子們負責躲藏,jiajia負責找,而wind負責操縱這n個屋子的燈。在起初的
時候,所有的燈都沒有被開啟。每一次,孩子們只會躲藏在沒有開燈的房間中,但是為了增加刺激性,孩子們會要
求開啟某個房間的電燈或者關閉某個房間的電燈。為了評估某一次遊戲的複雜性,jiajia希望知道可能的最遠的兩
個孩子的距離(即最遠的兩個關燈房間的距離)。 我們將以如下形式定義每一種操作: c(hange) i 改變第i個房
間的照明狀態,若原來開啟,則關閉;若原來關閉,則開啟。 g(ame) 開始一次遊戲,查詢最遠的兩個關燈房間的
距離。input
第一行包含乙個整數n,表示房間的個數,房間將被編號為1,2,3…n的整數。接下來n-1行每行兩個整數a, b,
表示房間a與房間b之間有一條走廊相連。接下來一行包含乙個整數q,表示操作次數。接著q行,每行乙個操作,如
上文所示。
output
對於每乙個操作game,輸出乙個非負整數到hide.out,表示最遠的兩個關燈房間的距離。若只有乙個房間是關
著燈的,輸出0;若所有房間的燈都開著,輸出-1。
sample input
1 22 3
3 43 5
3 66 7
6 8g
c 1g
c 2g
c 1g
sample output
4 hint
對於100%的資料, n ≤100000, m ≤500000。
啊總算a了這道動態點分治了, 感覺點分樹這個名字好高大上的樣子…
相比於原來的點分, 動態點分治是建了一棵點分樹, 每個重心向它子樹里下一層重心連邊, 就成了一棵點分樹, 感覺跟支配樹的構造有點相似. 由於重心所以樹高是log級別的, 所以暴力跳支配樹fa.
第一次寫引用了黃學長的**…
順便粘一下hzwer的題解.
一開始寫的可並堆感覺自己快炸了…**還是很清晰的, 雖然有180行….其實這種做法不難。。。就是**長。。。
把每次分治的重心連成一棵樹,樹的深度是logn,每次修改乙個結點只影響它到樹根的一條鏈
這題具體實現的時候要維護三層堆
c.每個重心存所有子樹到其距離
b.每個重心存各個子樹最大值,即子結點堆c的最大值
a.全域性乙個堆,維護答案最大值,存每個堆b的最大值和次大值之和
樹上距離用rmq來求比較優越2333
#include
#include
#include
#define boc register char
#define acce register int
#define prio priority_queue
using
namespace
std;
const
int p = 22;
const
int inf = 1e9 + 7;
const
int maxn = 1e5 + 5;
const
int dblmaxn = 2e5 + 10;
int n, num, tot, idx, sum, root, t;
char ss[2];
bool vis[maxn], sta[maxn];
int st[p][dblmaxn], lg[dblmaxn], in[maxn], h[maxn], dep[maxn], f[maxn], fa[maxn], siz[maxn], pw[p];
inline
const
int read()
struct edgee[dblmaxn];
struct heap
inline
void erase(int x)
inline
void pop()
inline
int top()
inline
int size()
inline
int stop()
}a, b[maxn], c[maxn];
inline
void add(int u, int v)
void dfs(int u, int tfa)
}void getrt(int u, int tfa)
f[u] = max(f[u], sum - siz[u]);
if (f[u] < f[root]) root = u;
}void divi(int u, int dfa)
}inline
int query(int u, int v)
inline
int dis(int u, int v)
inline
void turn_off(int u)
}u = f;
}}inline
void turn_on(int u)
}u = f;
}}inline
void init()
int main()
else
}}
點分樹 ZJOI2007 捉迷藏
門 點分樹不卡常就別想過了。問樹中最遠黑點對距離 帶修改點分樹入門作 原圖先亂跑一次點分治,儲存點分治的每個root之間的父子關係,得到一顆點分樹。然後我們的原圖除了求dis就可以不管了 學習題解中不認識的大佬所說的套路 點分治得到點分樹 每個點用s1,s2 s 1,s 2 s1 s2 兩個資料結構...
動態點分治 bzoj 3730,bzoj 1095
總結一下動態點分治的模板。對於乙個樹,把它點分的同時記錄每個點的所有父親 logn個 並記錄點距其父親的距離。具體實現就是dfs的時候fa x dep x u,dis x dep x d bzoj1095 您需要寫乙個程式支援反轉點的顏色,求距離最遠的黑色點對的距離。解析 在每個點u存乙個堆st記錄...
bzoj4012 動態點分治 卡常數
這是一種型別的動態點分治 動態點分治,關鍵還是要在均攤n的空間複雜度記憶體下所有東西。這個就要充分利用stl,比如vector 每乙個點存以這個點為根點分治的資訊。對於詢問乙個點的路徑時,就是沿著點分治樹,不斷朝fa走,每走一層統計一下,因為分治樹可以保證在log層內,時間複雜度同階 卡常數無優化 ...