資料結構 並查集 奇偶遊戲(做法1)

2021-10-03 15:32:23 字數 2359 閱讀 4299

並查集有兩個擴充套件應用,乙個是帶邊權的並查集另乙個是帶擴充套件域的並查集。這道題用兩種方法都可以做。值得學習。

題目:奇偶遊戲

做法1:帶邊權的並查集

1、用 sum

[x

]sum[x]

sum[x]

表示 1

11到 x

xx 中1的個數(此處 sum

[x

]sum[x]

sum[x]

不需要具體求出),讀入「l,r

,rel

l,r,rel

l,r,re

l」,如果 rel

=odd

rel=odd

rel=od

d,那麼證明 sum

[l−1

]sum[l-1]

sum[l−

1]和 sum

[r

]sum[r]

sum[r]

奇偶性不同(字首和的思想),反之則相同。

2、有了這個操作,我們就可以把輸入資料當作 x1,

x2,.

..

x_1,x_2,...

x1​,x2

​,..

. 和他們奇偶性的關係,如果是奇偶性不同,兩個元素之間則連線一條邊權為 1 的邊反之為 0 。此時,記 d[x

]d[x]

d[x]

為 xx

x 到 p[x

]p[x]

p[x]

的奇偶性。同時,這些元素的關係具有傳遞性,可以相互推出,所以把可以推出的元素放在乙個集合裡,用並查集維護 d[x

]d[x]

d[x]

。3、接下來並查集維護時面臨兩個問題:

a)呼叫 find() 函式時子節點直接指向根節點過程中邊權的計算

本質上就是亦或運算(xor

xorxo

r),因為相同出 0,不同出 1,即奇+奇=偶,偶+偶=偶,奇+偶=奇,這也與上面的定義正好一致。

b)合併兩顆樹時加的那一條邊的邊權的計算;(以 p[x

]=fi

nd(y

)p[x]=find(y)

p[x]=f

ind(

y)操作說明)

這裡不難看出公式 rel

(x,y

)=d[

x]

rel(x,y)=d[x]

rel(x,

y)=d

[x]xor

xorxord[

y]

d[y]

d[y]

x or

xorxord[

p[x]

]d[p[x]]

d[p[x]

],則可以得到新加的邊權計算公式為:d[p

[x]]

=d[x

]d[p[x]]=d[x]

d[p[x]

]=d[

x]x or

xorxord[

y]

d[y]

d[y]

x or

xorxorre

l(x,

y)

rel(x,y)

rel(x,

y).4、最後要注意離散化資料,這裡不要求保序性,所以用偷個懶用 map

mapma

p 好了。

**

#include

#include

#include

#include

#include

using

namespace std;

const

int n=

10010

;unordered_map<

int,

int> mp;

int p[n*2]

,d[n*2]

;struct nodeq[n]

;int n,m,tot;

intdis

(int x)

intfind

(int x)

return p[x];}

intget

(char x)

intmain()

for(

int i=

1;i<=tot;i++

) p[i]

=i;for

(int i=

1;i<=m;i++

)else}}

cout

}

奇偶遊戲 帶權並查集

奇偶遊戲 首先需要知道異或這種東西 兩個數異或的結果是什麼 兩個數按位做差的絕對值 異或相當於 模2 做加法 只看最後一位 例如 5 101 3 011 只看最後以為為0 就是偶數,奇數加奇數為偶數,這一題用到此方法 1個數異或自己為0 乙個數異或0 還是自己 定義s i 為前i個數又多少個奇數1 ...

資料結構 並查集

並查集,顧名思義,合併 查詢 集合 並查集是一種樹型的資料結構,用於處理一些不相交集合 disjoint sets 的合併及查詢問題。常常在使用中以森林來表示。對於概念等等的這裡不再贅述,直接講解應用。應用1 判斷圖中有多少聯通分量 或者圖是否聯通 聯通分量 1 hdu 1213 應用2 判斷圖是否...

資料結構 並查集

time limit 1000ms memory limit 65536k 某城市有n個人,現在給定關於n個人的m條資訊,m條資訊是兩個人在同乙個小區,根據所給資訊,判斷這個城市最多可能有多少個小區。n個人編號為1 n。多組輸入。每組第一行有兩個整數n,m 2 n 50000,0 m n 2 接下來...