답안 #370123

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
370123 2021-02-23T10:45:25 Z AriaH Raspad (COI17_raspad) C++11
0 / 100
3290 ms 80728 KB
/** Im the best because i work as hard as i possibly can **/

///#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#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];

pii RI[N * M];

ll tot, ps[N], cnt[N];

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

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

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

void solve(int l, int r)
{
	if(l > r) return;
	if(l == r)
	{
		///ll cu = 0;
		for(int j = 1; j <= m; j ++)
		{
			tot += A[l][j];
			tot -= (A[l][j] + A[l][j - 1] == 2);
		}
		///printf("l = %d r = %d cu = %lld\n", l, r, cu);
		return;
	}
	int mid = (l + r) >> 1;
	solve(l, mid); solve(mid + 1, r);
	///printf("l = %d r = %d\n", l, r);
	cnt[l - 1] = cnt[r + 1] = ps[l - 1] = ps[r + 1] = 0;
	for(int i = l; i <= r; i ++)
	{
		for(int j = 1; j <= m; j ++)
		{
			ps[i] = 0;
			par[I[i][j]] = I[i][j];
			cnt[i] = 0;
			arr[i][j] = 0;
		}
	}
	vector < ll > merges;
	merges.push_back(mid + 1);
	///printf("show arr : \n");
	for(int i = mid + 1; i <= r; i ++)
	{
		if(i > mid + 1) cnt[i] = cnt[i - 1];
		for(int j = 1; j <= m; j ++)
		{
			cnt[i] += A[i][j];
			cnt[i] -= unify(I[i][j], I[i][j - 1]);
		}
		///printf("\n");
		if(i > mid + 1)
		{
			for(int j = 1; j <= m; j ++)
			{
				cnt[i] -= unify(I[i][j], I[i - 1][j]);
			}
		}
		for(int j = 1; j <= m; j ++) arr[i][j] = get(I[mid + 1][j]);/// printf("%d ", arr[i][j]);
		if(i > mid + 1)
		{
			int flag = 0;
			for(int j = 1; j <= m; j ++)
			{
				if(A[mid + 1][j] == 0) continue;
				if(arr[i][j] != arr[i - 1][j]) flag = 1;
			}
			if(flag) merges.push_back(i);
		}
		ps[i] = cnt[i];
		if(i > mid + 1) ps[i] += ps[i - 1];
		///printf("phase 1, i = %d cnt = %lld ps = %lld\n", i, cnt[i], ps[i]);
	}
	///printf("\n");
	merges.push_back(r + 1);
	/*printf("phase 2\n");
	for(auto x : merges)
	{
		printf("%lld ", x);
	}
	printf("\n");
	*/
	if(SZ(merges) > M + 10)
	{
	    printf("impossible");
	    return;
	}
	ll cu = 0;
	for(int i = mid; i >= l; i --)
	{
		for(int j = 1; j <= m; j ++)
		{
			cu += A[i][j];
			cu -= unify(I[i][j], I[i][j - 1]);
		}
		if(i < mid)
		{
			for(int j = 1; j <= m; j ++)
			{
				cu -= unify(I[i][j], I[i + 1][j]);
			}
		}
		///printf("phase 3 i = %d cu = %lld\n", i, cu);
		for(int id = 0; id < SZ(merges) - 1; id ++)
		{
			map < pll , int > mp;
			ll yal = 0;
			for(int j = 1; j <= m; j ++)
			{
				if(A[mid][j] + A[mid + 1][j] < 2) continue;
				ll v = get(I[mid][j]), u = arr[merges[id]][j];
				///printf("wtf is wrong v = %lld u = %lld\n", v, u);
				if(mp.find(Mp(v, u)) == mp.end()) yal ++;
				mp[Mp(v, u)] = 1;
				mp[Mp(u, v)] = 1;
			}
			///printf("id = %d yal = %lld\n", id, yal);
			tot += 1ll * (cu - yal) * (merges[id + 1] - merges[id]) + (ps[merges[id + 1] - 1] - ps[merges[id] - 1]);
		}
	}
}

int main()
{
	scanf("%d%d", &n, &m);
	RI[0] = Mp(0, 0);
	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:166:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  166 |  scanf("%d%d", &n, &m);
      |  ~~~~~^~~~~~~~~~~~~~~~
raspad.cpp:178:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  178 |   scanf("%s", C);
      |   ~~~~~^~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 364 KB Output is correct
2 Incorrect 6 ms 492 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 364 KB Output is correct
2 Incorrect 6 ms 492 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 426 ms 39916 KB Output is correct
2 Correct 950 ms 80620 KB Output is correct
3 Incorrect 3290 ms 80728 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 364 KB Output is correct
2 Incorrect 6 ms 492 KB Output isn't correct
3 Halted 0 ms 0 KB -