传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1453
用线段树维护每行,每个节点套并查集,记录最上方和最下方的联通性,暴力合并暴力修改并查集,记录答案,
并查集的合并比较恶心,我yy了很久……(请读者自行思考)
我用并查集中的1..n表示上方,n+1..2n表示下方,合并时2n+1..4n用于右侧的上下方并查集
Code:
#include<bits/stdc++.h>
using namespace std;
struct ufset{
vector<int>fa;
int n;
void init(int _n){n=_n;fa.resize(n+1);for(int i=1;i<=n;++i)fa[i]=i;}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void merge(int x,int y){fa[find(x)]=find(y);}
bool same(int x,int y){return find(x)==find(y);}
int& at(int x){return fa[x];}
};
int n,m,a[201][201];
int mp[801];
struct sgt{
struct node{
ufset U;
int w,b;
int& at(int x){return U.at(x);}
node(){w=b=0;}
}t[201<<2];