poj1733 離散化 帶權並查集的思考

2021-07-24 19:48:15 字數 1499 閱讀 8256

題意是給你乙個區間和區間1的個數是偶數還是奇數 然後判斷第乙個錯提問的   第一眼看到這題感覺是線段樹 思考一下線段樹的做法 線段樹維護區間資訊 維護乙個區間是奇數還是偶數 線段樹乙個節點代表乙個區間 但是乙個區間並不代表乙個節點 要多個節點儲存乙個資訊 多個交叉區間維護的話 就亂掉了 而且一般線段樹題是多次詢問 所以線段樹不行,這個題就是維護區間資訊

那麼維護資料資訊的資料結構有哪幾種 1:線段樹(排除) 2:排序二叉樹(相關的也不用想)3:優先佇列(不用想)4;並查集(哎,這個可以)。。。好像所有的資料結構都是用來維護資料的

用並查集無非就是建立集合 集合中的元素在某種關係下是平等的 所以構成乙個集合 並查集就是維護節點與節點的資訊和節點與根節點的關係這兩種維護方法 

這道題是乙個區間?這就有點怪了 區間怎麼用並查集維護?  節點與節點嗎? 不行! 如果節點與節點代表乙個區間 那麼乙個集合的多個節點 我怎麼知道哪個是哪個區間 所以不能維護  那麼就是節點與根節點的 根節點與子節點構成乙個區間 埃 這好像也不行啊 根節點只有乙個啊  如果我區間有乙個是子節點 而另乙個不屬於這個集合 那我怎麼維護啊 比如 【1,3】這個操作完之後就是1為根結點 3是子節點 如果這時候【3,4】那麼怎麼維護啊  其實這個就是帶權並查集 本來是【3,4】經過帶權並查集操作 變成【1,4】的資訊 還有就是這道題給的是兩段都是閉區間 要左區間減1變成半閉半開 要不然不能並(這個其實剛開始看的時候很難想出來,對我來說)

這代替維護的就是奇偶性

#include#include#include#include#includeusing namespace std;

#define maxn 5005

int pa[maxn],d[maxn],v[maxn],co=1,k=1;

long long le[maxn],re[maxn],p[2*maxn],ans;

long long find(int x)

else

return x;

}int unite(int lx,int rx,int qu)

else

return false;

}int main()

{ long long tot;

int n;char ch[6];

while(scanf("%i64d",&tot)!=eof)

{ scanf("%d",&n);co=0;k=0;ans=0;

for(int i=0;i

因為fx的子節點d[x]到fx的關係是正確的 只要改變d[fx]就行了 後面的子節點後面find函式的會更新 這就是上面為什麼不要一步直接更新到根結點的原因 按乙個公式 fx->fy =d[fx]  x->fx =d[x] y->fy=d[y] x->y =qu

看圖-》

poj 1733 帶權並查集 離散化

思路 這題一看就想到要用並查集做了,不過一看資料這麼大,感覺有點棘手,其實,我們仔細一想可以發現,我們需要記錄的是出現過的節點到根節點的1個奇偶性,這與區間端點的大小並沒有關係,於是想到我們可以用map對映即可,這樣就解決了大資料了。此外,如果0表示出現偶數個1,1表示出現奇數個1,然後就是向量偏移...

poj1733 帶權並查集 map

開始看題目姿勢不對,然後發現是n的長度是1000000000不是串的長度,又發現輸出是最多符合前幾項 這類區間並查集都維護乙個權值終於感覺理解了,左區間需要 1 由於陣列開不下,但詢問只有5000條就可以用map存,hash不會。還是re因為初始化的時候不是for i,1,n 是for i,1,50...

poj1733 種類並查集 離散化

題意 輸入n表示有乙個長度為n的0,1字串,m表示接下來有m行輸入,接下來的m行輸入中x,y,even表示第x到第y個字元中間1的個數為偶數個,x,y,odd表示第x到第y個字元中間1的個數為奇數個,若m句話中第k 1是第一次與前面的話矛盾,輸出k 思路 若x,y之間1的個數為偶數個,那麼1 x 與...