bzoj3757 蘋果樹 樹上莫隊

2021-09-25 22:23:37 字數 2072 閱讀 3796

題目大意:

給定一棵n

nn個節點的樹,每個節點有乙個顏色a

ia_i

ai​。

有m

mm個詢問,每次給出u,v

,a,b

u,v,a,b

u,v,a,

b,表示u

uu到v

vv的路徑上,把所有顏色a

aa看成顏色b

bb,求出有多少種顏色。

詢問不會修改節點真實的顏色。

n

<

=50000.

n<=50000.

n<=5

0000

. 如果這是乙個序列,那麼顯然是乙個無修改莫隊就解決了qwq。

然後把詢問放在樹上,就在樹上進行莫隊就吼了。

樹上莫隊方法參考:蒟蒻的題解qwq

然後把所有顏色a

aa看成b

bb,就判斷一下:如果a

aa和b

bb都出現了,那麼答案要-1(比較水qwq)。

#include

#include

#include

#include

#define re register int

#define rl register ll

using

namespace std;

typedef

long

long ll;

intread()

while

(ch>=

'0'&& ch<=

'9')

return x*f;

}inline

char

getchar()

namespace i_love w[size<<1]

;void

addedge

(int u,

int v)

int tim,l[size]

,r[size]

,order[size<<1]

;int deep[size]

,anc[size]

[log]

;void

dfs(

int x,

int fa)

for(

int i=head[x]

; i; i=w[i]

.next)

} order[r[x]

=++tim]

=x;}

intlca

(int u,

int v)}if

(u==v)

return u;

for(re i=maxn; i>=

0; i--)}

return anc[u][0

];}int ans,vis[size<<1]

,out[size<<1]

;bool flag[size<<1]

;inline

void

upd(

int x)

else

}int id,l,r,a,b,lca;

} q[size]

;inline

bool

comp

void

fujibayashi_ryou()

for(re i=

1; i<=n; i++

)else

}dfs

(root,0)

;for

(re i=

1; i<=m; i++

)else

}sort

(q+1

,q+1

+m,comp)

;int l=

1,r=0;

for(re i=

1; i<=m; i++

)else

if(q[i]

.lca)

upd(q[i]

.lca);}

for(re i=

1; i<=m; i++)}

}int

main()

BZOJ 3757 蘋果樹 樹上莫隊

題目大意 給定一棵樹,每個節點有乙個顏色,多次求兩個節點的路徑上有多少種不同的顏色 其中還有兩個引數a和b,若蘋果樹上同時有這兩種顏色,ans 傳說中的樹上莫隊 顏色數既不滿足區間加法也不滿足區間減法,直接維護極其困難,這種東西就直接考慮莫隊好了 但是怎麼轉移是個問題 首先樹分塊 然後以左端點所在塊...

BZOJ3757 蘋果樹 樹上莫隊

樹上莫隊共有三種寫法 1.按dfs序列分塊,和普通莫隊類似。常數大,不會被卡。2.按塊狀樹的方式分塊。常數小,會被菊花圖卡到o n 3.按 bzoj1086 王室聯邦的方式分塊。常數小,不會被卡。唯一的缺點是較抽象,乙個塊可能是不連通的。權衡一下當然還是寫第三種做法,具體看 然後還有乙個問題,手動模...

BZOJ3757 蘋果樹(樹上莫隊)

點此看題面 大致題意 每次問你樹上兩點之間路徑中有多少種顏色,每次詢問可能會將一種顏色 a 看成 b 這題是一道樹上莫隊板子題。畢竟求區間中有多少種不同的數是莫隊演算法的經典應用啊。這操作其實很好處理。只要判斷 cnt a 和 cnt b 是否同時 0 即可。但要注意特判 a b 的情況。inclu...