답안 #370304

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
370304 2021-02-23T17:14:38 Z AriaH Raspad (COI17_raspad) C++11
61 / 100
6000 ms 100844 KB
/** Im the best because i work as hard as i possibly can **/
 
#pragma GCC optimize("O2")
#include <bits/stdc++.h>
using namespace std;
 
typedef long long                   ll;
typedef long double                 ld;
typedef pair<int,int>               pii;
typedef pair<ll,ll>                 pll;
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second
#define Mp                          make_pair
#define fast_io                     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define file_io                     freopen("in.txt" , "r+" , stdin) ; freopen("out.txt" , "w+" , stdout);
#define endl                        "\n"
#define SZ(x)						(int)x.size()
 
const int N = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll mod2 = 998244353;
const ll inf = 8e18;
const int LOG = 22;
const int M = 52;
 
char C[N];
 
int n, m, A[N][M], I[N][M], par[N * M], arr[N][M], par2[N * M];
 
pii RI[N * M];
 
ll tot, ps[N], cnt[N];

/// unify tp = 0 for the left side  &   unify tp = 1 for right side     unify2 for the merge of left and right

inline int ok(int i) { return A[RI[i].F][RI[i].S]; }

int get2(int x) { return (x == par2[x]? x : par2[x] = get2(par2[x])); }

int get(int x) { return (x == par[x]? x : par[x] = get(par[x])); }

int unify(int v, int u, int tp)
{
	if(tp == 0)
	{
		if(v < u) swap(u, v);
	}
	else
	{
		if(u < v) swap(u, v);
	}
	if(!ok(v) || !ok(u)) return 0;
	v = get(v), u = get(u);
	if(v == u) return 0;
	par[u] = v;
	return 1;
}

int unify2(int v, int u)
{
	if(!ok(v) || !ok(u)) return 0;
	v = get2(v), u = get2(u);
	if(v == u) return 0;
	par2[u] = v;
	return 1;
}

ll jam(int l, int r, int tp, int mid)
{
	if(tp == 0)
	{
		r ++;
		return (l > mid? 0 : ps[l]) - (r > mid? 0 : ps[r]);
	}
	else
	{
		l --;
		return (r <= mid? 0 : ps[r]) - (l <= mid? 0 : ps[l]);
	}
}

inline void Reset(int x)  { par2[x] = x; }

void solve(int l, int r)
{
	if(l > r) return;
	if(l == r)
	{
		for(int j = 1; j <= m; j ++)
		{
			tot += A[l][j];
			tot -= (A[l][j] + A[l][j - 1] == 2);
		}
		return;
	}
	int mid = (l + r) >> 1;
	solve(l, mid); solve(mid + 1, r);
	cnt[l - 1] = cnt[r + 1] = ps[l - 1] = ps[r + 1] = 0;
	for(int i = l; i <= r; i ++)
	{
		ps[i] = cnt[i] = 0;
		for(int j = 1; j <= m; j ++)
		{
			par[I[i][j]] = I[i][j];
			arr[i][j] = 0;
		}
	}
	///printf("l = %d r = %d\n", l, r);
	vector < int > L, R;
	/// compressing the right side
	R.push_back(mid + 1);
	for(int i = mid + 1; i <= r; i ++)
	{
		for(int j = 1; j <= m; j ++)
		{
			cnt[i] += A[i][j];
			cnt[i] -= unify(I[i][j], I[i][j - 1], 1);
		}
		if(i > mid + 1)
		{
			cnt[i] += cnt[i - 1];
			for(int j = 1; j <= m; j ++)
			{
				cnt[i] -= unify(I[i][j], I[i - 1][j], 1);
			}
		}
		ps[i] = cnt[i];
		for(int j = 1; j <= m; j ++)
		{
			arr[i][j] = get(I[mid + 1][j]);
		}
		if(i > mid + 1)
		{
			ps[i] += ps[i - 1];
			int flag = 0;
			for(int j = 1; j <= m; j ++)
			{
				if(!A[mid + 1][j]) continue;
				if(arr[i][j] != arr[i - 1][j]) flag = 1;
			}
			if(flag) R.push_back(i);
		}
	}
	R.push_back(r + 1);
	/// end
	/// compressing the left side
	L.push_back(mid);
	for(int i = mid; i >= l; i --)
	{
		for(int j = 1; j <= m; j ++)
		{
			cnt[i] += A[i][j];
			cnt[i] -= unify(I[i][j], I[i][j - 1], 0);
		}
		if(i < mid)
		{
			cnt[i] += cnt[i + 1];
			for(int j = 1; j <= m; j ++)
			{
				cnt[i] -= unify(I[i][j], I[i + 1][j], 0);
			}
		}
		ps[i] = cnt[i];
		for(int j = 1; j <= m; j ++)
		{
			arr[i][j] = get(I[mid][j]);
		}
		if(i < mid)
		{
			ps[i] += ps[i + 1];
			int flag = 0;
			for(int j = 1; j <= m; j ++)
			{
				if(!A[mid][j]) continue;
				if(arr[i][j] != arr[i + 1][j]) flag = 1;
			}
			if(flag) L.push_back(i);
		}
	}
	L.push_back(l - 1);
	/// end
	/*printf("arr : \n");
	for(int i = l; i <= r; i ++)
	{
		printf("i = %d\n", i);
		for(int j = 1; j <= m; j ++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	printf("ps & cnt\n");
	for(int i = l; i <= r; i ++)
	{
		printf("%lld %lld   ", cnt[i], ps[i]);
	}
	printf("\n showing L & R\n");
	for(auto x : L) printf("%d ", x);
	printf("\n");
	for(auto x : R) printf("%d ", x);
	printf("\n");
	*/
	for(int i1 = 0; i1 < SZ(L) - 1; i1 ++)
	{
		for(int i2 = 0; i2 < SZ(R) - 1; i2 ++)
		{
			for(int j = 1; j <= m; j ++)
			{
				Reset(arr[L[i1]][j]); Reset(arr[R[i2]][j]);
			}
			ll yal = 0;
			for(int j = 1; j <= m; j ++)
			{
				yal += unify2(arr[L[i1]][j], arr[R[i2]][j]);
			}
			///printf("i1 = %d i2 = %d yal = %lld jamleft = %lld jam right = %lld\n", i1, i2, yal, jam(L[i1 + 1] + 1, L[i1], 0, mid), jam(R[i2], R[i2 + 1] - 1, 1, mid));
			ll szl = (L[i1] - L[i1 + 1]), szr = R[i2 + 1] - R[i2];
			tot += jam(L[i1 + 1] + 1, L[i1], 0, mid) * szr +  jam(R[i2], R[i2 + 1] - 1, 1, mid) * szl - yal * szl * szr;
		}
	}
	///printf("tot = %lld\n", tot);
}
 
int main()
{
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; i ++)
	{
	    for(int j = 1; j <= m; j ++)
	    {
		I[i][j] = (i - 1) * m + j;
		RI[I[i][j]] = Mp(i, j);
	    }
	}
	for(int i = 1; i <= n; i ++)
	{
		scanf("%s", C);
		for(int j = 0; j < m; j ++)
		{
			A[i][j + 1] = (C[j] == '1');
		}
	}
	solve(1, n);
	printf("%lld\n", tot);
	return 0;
}

Compilation message

raspad.cpp: In function 'int main()':
raspad.cpp:227:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  227 |  scanf("%d%d", &n, &m);
      |  ~~~~~^~~~~~~~~~~~~~~~
raspad.cpp:238:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  238 |   scanf("%s", C);
      |   ~~~~~^~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 492 KB Output is correct
2 Correct 4 ms 492 KB Output is correct
3 Correct 2 ms 492 KB Output is correct
4 Correct 1 ms 492 KB Output is correct
5 Correct 2 ms 492 KB Output is correct
6 Correct 2 ms 492 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 492 KB Output is correct
2 Correct 4 ms 492 KB Output is correct
3 Correct 2 ms 492 KB Output is correct
4 Correct 1 ms 492 KB Output is correct
5 Correct 2 ms 492 KB Output is correct
6 Correct 2 ms 492 KB Output is correct
7 Correct 18 ms 1644 KB Output is correct
8 Correct 1 ms 748 KB Output is correct
9 Correct 45 ms 1772 KB Output is correct
10 Correct 11 ms 1516 KB Output is correct
11 Correct 25 ms 1772 KB Output is correct
12 Correct 17 ms 1388 KB Output is correct
13 Correct 24 ms 1644 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 507 ms 42860 KB Output is correct
2 Correct 1068 ms 86508 KB Output is correct
3 Correct 1512 ms 86764 KB Output is correct
4 Correct 608 ms 77804 KB Output is correct
5 Correct 277 ms 26220 KB Output is correct
6 Correct 1121 ms 86636 KB Output is correct
7 Correct 930 ms 86636 KB Output is correct
8 Correct 794 ms 69292 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 492 KB Output is correct
2 Correct 4 ms 492 KB Output is correct
3 Correct 2 ms 492 KB Output is correct
4 Correct 1 ms 492 KB Output is correct
5 Correct 2 ms 492 KB Output is correct
6 Correct 2 ms 492 KB Output is correct
7 Correct 18 ms 1644 KB Output is correct
8 Correct 1 ms 748 KB Output is correct
9 Correct 45 ms 1772 KB Output is correct
10 Correct 11 ms 1516 KB Output is correct
11 Correct 25 ms 1772 KB Output is correct
12 Correct 17 ms 1388 KB Output is correct
13 Correct 24 ms 1644 KB Output is correct
14 Correct 507 ms 42860 KB Output is correct
15 Correct 1068 ms 86508 KB Output is correct
16 Correct 1512 ms 86764 KB Output is correct
17 Correct 608 ms 77804 KB Output is correct
18 Correct 277 ms 26220 KB Output is correct
19 Correct 1121 ms 86636 KB Output is correct
20 Correct 930 ms 86636 KB Output is correct
21 Correct 794 ms 69292 KB Output is correct
22 Correct 2583 ms 100844 KB Output is correct
23 Execution timed out 6049 ms 96996 KB Time limit exceeded
24 Halted 0 ms 0 KB -