WC2005 雙面棋盤 並查集 分治

2022-07-13 20:21:25 字數 1968 閱讀 4817

題目描述

題解

唉,還是碼力不行,寫了乙個多小時發現想錯了又重構了乙個多小時。

這道題意圖很顯然,動態維護聯通塊,有乙個經典做法就是用lct維護按照刪除時間維護的最大生成樹。

網上還有一種神奇的做法,線段樹套並查集,蒟蒻表示不懂。。

這道題可以利用並查集操作可以撤銷這種性質來做。

線段樹分治

線段樹分治可以分兩種情況,操作之間獨立和操作之間不獨立。

操作之間獨立意味著我先完成哪個操作就可以,例如找最優點,有一道例題。

還有一種是操作之間是可以相互影響的,比如說這道題,連通性這種東西和我加的每一條邊都有關。

**

#include#include

#include

#include

#define n 40002

#define maxn 209

using

namespace

std;

int n,id[maxn][maxn],f[n],tot,ls[n<<1],rs[n<<1],b[n],bl,w[n],wl,deep[n],num,last[n<<1

],m,root,a[maxn][maxn],bian;

int tag[maxn][maxn][4],anti[4],color[n<<1

];const

int dx[4]=;

const

int dy[4]=;

inline

intrd()

while(isdigit(c))

return f?-x:x;

}int find(int x)

struct node;

struct rbs;

struct node2;

vector

vec[n<<1

];vector

zh[n<<1

];node2 linko[n

<<1

];void upd(int &cnt,int l,int r,int l,int r,int x,int

y));return

;}

int mid=(l+r)>>1

;

if(mid>=l)upd(ls[cnt],l,mid,l,r,x,y);

if(mid1

,r,l,r,x,y);

}void solve(int &cnt,int l,int

r));

f[yy]=xx;deep[xx]=max(deep[xx],deep[yy]+1

); }

}

//cout

else

while

(zh[cnt].size())

}int

main()

for(int i=1;i<=num;++i)f[i]=i,deep[i]=1

; memset(last,-1,sizeof

(last));

for(int i=1;i<=n;++i)

for(int j=1;j<=n;++j)

for(int k=0;k<2;++k);

}m=rd();

for(int i=1;i<=m;++i)

a[x][y]^=1

; }

for(int i=1;i<=n;++i)

for(int j=1;j<=n;++j)

for(int k=0;k<2;++k)

solve(root,

0,m);

return0;

}

WC2005 友好的生物

這題算是毒瘤吧,看到這個題我除了o n 2 想不到別的方法 後來嘗試使用平方的方式亂搞,但是給出了反例 在看了國家集訓隊ysy的解題報告後方才明白 思路是一種放寬的思路 我們列舉每個差值的符號,在其中列舉最大值,就可以有效去除絕對值 最後按照第k位從小到大排序,來列舉 從小到大進行掃瞄,每次用當前的...

WC 2005 dface 雙面棋盤

其實就是個線段樹 並查集維護,原來的每行看做線段樹的乙個底層節點,線段樹每個節點2 n的空間建立乙個並查集,兩個節點合併時維護塊的個數資訊,然後捨棄中間部分保留外圍部分重建並查集就可以了。我寫的是zkw線段樹,用這方法就算不是黑白雙色也可以的吧。本人弱菜。include include includ...

luogu4131 WC2005 友好的生物

wc2005 友好的生物 還有2006陳啟峰的 一張一弛,解題之道 part 2 先由簡,不考慮a k 那麼這樣直接求怎麼求呢?直接列舉o n2k 當然可以,只不過會超時 有沒有一種方法可以避免一些不必要的列舉呢?這道題最大的阻礙就是這個絕對值問題了,因為它只跟兩個生物的具體屬性的相對大小有關,所以...