2019-10-28  2024-09-15    430 字  1 分钟

ComentOJ-C72-4032 「佛御石之钵 -不碎的意志-」(困难版)

每行开一个并查集,每个格子的祖先表示包括其在内的右边第一个为 0 的格子

一个总的并查集,表示两个格子是否属于一个集合。

时间复杂度 $math_inline$O\left( nm\alpha(nm) + nq \right)$math_inline$


Code
/* ***********************************************
Author        : Akvicor
Created Time  : Mon Oct 28 13:06:07 2019
File Name     : C2.cpp
************************************************ */

#include <bits/stdc++.h>

#define FAST_IO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
#define ASB using namespace std; typedef long long ll; namespace AkvicorS {
#define ASE } int main() { return AkvicorS::sol(); }

ASB

int n, m, q, x1, y1, x2, y2, ans, cnt;
char s[1010];

const int MAXN = 1e3+10;

int fa[MAXN][MAXN];
int F[MAXN*MAXN];
int id[MAXN][MAXN];

int fx[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

inline int find(int * f, int x){return f[x] == x ? x : f[x]=find(f, f[x]);}

void merge(int x, int y){
	++ans;
	id[x][y] = ++cnt; // the number of '1'
	F[cnt] = cnt; // every '1' is the father to itself
	int u = find(fa[x], y), v = find(fa[x], y+1); // '1' 's root is the next '0'
	if(u != v) fa[x][u] = v; 

	// check the left, right, up and down
	for(int i = 0; i < 4; ++i){
		int tx = x + fx[i][0];
		int ty = y + fx[i][1];
		if(tx && ty && tx <= n && ty <= m && id[tx][ty]){
			u = find(F, id[x][y]), v = find(F, id[tx][ty]);
			if(u != v){ // if u and v is two union before
				--ans;
				F[u] = v;
			}

		}
	}
}

void init(){
	for(int i = 0; i <= n; ++i){
		for(int j = 0; j <= m+1; ++j){ // Must (j <= m+1) else The line 33 while throw segment falt
			fa[i][j] = j;
		}
	}
}

int sol(){
  FAST_IO;
  
  cin >> n >> m;
	init();
	for(int i = 1; i <= n; ++i){
		cin >> (s+1);
		for(int j = 1; j <= m; ++j){
			if(s[j] == '1'){
				merge(i, j);
			}
		}
	}

	cin >> q;

	while(q--){
		cin >> x1 >> y1 >> x2 >> y2;
		for(int x = x1; x <= x2; ++x){
			for(int y = find(fa[x], y1); y <= y2; y = find(fa[x], y)){
				merge(x, y); // next '0' and merge
			}
		}
		cout << ans << endl;
	}	
  
  return 0;
}

ASE