[POI2018]Pow ó d ź

Posted by calande on Tue, 24 Dec 2019 23:02:50 +0100

Description
I'll give you a matrix of n*m. the walls of the boundary are all H. There will be walls in two adjacent lattices. I'll ask you how many different schemes you have to fill them with water.

Sample Input
3 2 2
1
1
1
1 2
1 1

Sample Output
65

You consider sorting the edges from small to large. You can sum two adjacent squares of an edge to a set of dyadic differences at a time and count the answers. For a connected block, their height up must be the same, and you can count the answers accordingly.

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
int _min(int x, int y) {return x < y ? x : y;}
int _max(int x, int y) {return x > y ? x : y;}
int read() {
	int s = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
	return s * f;
}

struct edge {
	int x, y, c;
} e[1100000];
int fa[510000], low[510000];
LL s[510000];

bool cmp(edge a, edge b) {return a.c < b.c;}

int findfa(int x) {
	if(fa[x] != x) fa[x] = findfa(fa[x]);
	return fa[x];
}

int main() {
	int n = read(), m = read(), H = read();
	int len = 0;
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j < m; j++) {
			e[++len].x = (i - 1) * m + j, e[len].y = (i - 1) * m + j + 1;
			e[len].c = read();
		}
	}
	for(int i = 1; i < n; i++) {
		for(int j = 1; j <= m; j++) {
			e[++len].x = (i - 1) * m + j, e[len].y = i * m + j;
			e[len].c = read();
		}
	} sort(e + 1, e + len + 1, cmp); LL ans = 0;
	for(int i = 1; i <= n * m; i++) low[i] = 0, s[i] = 1, fa[i] = i;
	int hh = n * m;
	for(int i = 1; i <= len; i++) {
		int fx = findfa(e[i].x), fy = findfa(e[i].y);
		if(fx != fy) {
			fa[fx] = fy;
			s[fy] = ((s[fx] + e[i].c - low[fx]) * (s[fy] + e[i].c - low[fy]) % mod) % mod;
			low[fy] = e[i].c; hh--;
		} if(hh == 1) {(ans += H - e[i].c) %= mod; break;}
	} (ans += s[findfa(1)]) %= mod;
	printf("%lld\n", ans);
	return 0;
}