SPOJ COT2 樹上莫隊

2021-08-20 07:41:47 字數 1569 閱讀 6283

(以下路徑都不包含

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個分成一塊。讀取所有的查詢按左端點所在塊排序。重點在於怎麼進行區間轉移...