Submission #370308

#TimeUsernameProblemLanguageResultExecution timeMemory
370308AriaHRaspad (COI17_raspad)C++17
61 / 100
6037 ms100864 KiB
/** Im the best because i work as hard as i possibly can **/ #pragma comment(linker, "/stack:200000000") #pragma GCC optimize("Ofast") #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx") #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 (stderr)

raspad.cpp:3: warning: ignoring #pragma comment  [-Wunknown-pragmas]
    3 | #pragma comment(linker, "/stack:200000000")
      | 
raspad.cpp: In function 'int main()':
raspad.cpp:229:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  229 |  scanf("%d%d", &n, &m);
      |  ~~~~~^~~~~~~~~~~~~~~~
raspad.cpp:240:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  240 |   scanf("%s", C);
      |   ~~~~~^~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...