(以下路徑都不包含
lca lca
) 考慮當前知道路徑(u
,v) (u,
v)
的資訊,想要知道(t
,v) (t,
v)
的資訊,只需把(u
,t) (u,
t)
上的點狀態取反即可,那麼複雜度是和(u
,t) (u,
t)
的長度相關的。
於是我們考慮把樹分塊,每當乙個點的子樹大小≥n
−−√ ≥
n就拎出來成為一塊。id
i idi
表示i i
號點所在塊的編號,那麼我們按(i
di,d
fni)
' role="presentation" style="position: relative;">(id
i,df
ni)(
idi,
dfni
)給詢問排序,不難證明複雜度是o(
nn−−
√)o (n
n)
模板題:spoj cot2
**:
#include
#include
#include
#include
#define n 40010
#define m 100010
#define pii pair
#define mp make_pair
#define fs first
#define sc second
using namespace std;
const int b=200;
int n,m,nc,nb,tote,to[n<<1],con[n<<1],nxt[n<<1],col[n],z[n],sz[n],blk[n],dfn[n],fa[n],ver[n<<1],tim,sta[n],top,lg[n<<1],cnt[n],ans;
bool vis[n];
pii st[20][n<<1];
intread()
struct node
q[m];
bool cmp(node a,node b)
bool cmpid(node a,node b)
void dfs(int v)
void init()
int lca(int
x,int
y)void update(int
x,int
y)int main()
dfs(1);
init();
for(int i=1;i<=m;i++);}
sort(q+1,q+m+1,cmp);
int curx=1,cury=1;ans=0;
for(int i=1;i<=m;i++)
sort(q+1,q+m+1,cmpid);
for(int i=1;i<=m;i++)
printf("%d\n",q[i].ans);
return
0;
}
SPOJ COT2 (樹上莫隊)
給你一棵大小為n nn的樹,每個點都有點權。現在有m mm個詢問,每個詢問給你乙個兩個數a,b a,ba,b,問你從點a aa到點b bb之間的路徑中不同的點權的個數。萬惡的spoj並沒有寫點權的資料範圍,害我我先re 此題需要離散化點權 求解帶有詢問的不同數的個數這類題,一看就相當莫隊 但是因為莫...
SPOJ COT2 (樹上莫隊)
給你一棵大小為 n 的樹,每個點都有點權。現在有 m 個詢問,每個詢問給你乙個兩個數 a,b 問你從點 a 到點 b 之間的路徑中不同的點權的個數。萬惡的spoj並沒有寫點權的資料範圍,害我我先re 此題需要離散化點權 求解帶有詢問的不同數的個數這類題,一看就相當莫隊 但是因為莫隊只能夠在乙個序列上...
SPOJ COT2 樹上的莫隊演算法,樹上區間查詢
題意 n個節點形成的一棵樹。每個節點有乙個值。m次查詢,求出 u,v 路徑上出現了多少個不同的數。樹上的莫隊演算法,同樣將樹分成siz sqrt n 塊,然後離線操作。先對樹dfs一遍,每當子樹節點個數num siz,就將這num個分成一塊。讀取所有的查詢按左端點所在塊排序。重點在於怎麼進行區間轉移...