Submission #771338

#TimeUsernameProblemLanguageResultExecution timeMemory
771338TimDeeRectangles (IOI19_rect)C++17
50 / 100
5055 ms385856 KiB
#include "rect.h" #include <bits/stdc++.h> using namespace std; #define forn(i,n) for(int i=0; i<n; ++i) #define pi pair<int,int> #define f first #define s second #define ll long long #define pb push_back #define all(x) x.begin(),x.end() struct DSU { vector<int> p, sz, l, r, t, d; int m; DSU(int n, int _m) { m=_m; forn(i,n*m) { p.pb(i); sz.pb(1); l.pb(i%m); r.pb(i%m); t.pb(i/m); d.pb(i/m); } } int get(int u) { return p[u]==u?u:get(p[u]); } void uni(int u, int v) { u=get(u), v=get(v); if (u==v) return; if (sz[u]<sz[v]) swap(u,v); p[v]=u; sz[u]+=sz[v]; l[u]=min(l[u],l[v]); r[u]=max(r[u],r[v]); t[u]=min(t[u],t[v]); d[u]=max(d[u],d[v]); } void uni(int a, int b, int c, int d) { uni(a*m+b,c*m+d); } }; ll wrong(vector<vector<int>> b) { int n=b.size(), m=b[0].size(); vector<vector<int>> a(n+2,vector<int>(m+2,-1)); forn(i,n) forn(j,m) a[i+1][j+1]=b[i][j]; vector<pi> v; n+=2, m+=2; DSU dsu(n,m); forn(i,n) forn(j,m) if (a[i][j]!=-1) v.pb({a[i][j],i*m+j}); sort(all(v)); vector<vector<int>> ok(n,vector<int>(m,0)); forn(i,n) forn(j,m) { if (i==0 || i==n-1) ok[i][j]=1; if (j==0 || j==m-1) ok[i][j]=1; } forn(i,n) forn(j,m) if (ok[i][j]) dsu.uni(i,j,0,0); ll ans=0; int N=v.size(); for(int i=0; i<N; ) { vector<int> z; int x=v[i].f; while (i<N && v[i].f==x) { z.pb(v[i].s); ++i; } for(auto&it:z) { int x=it/m, y=it%m; if (ok[x-1][y]) dsu.uni(x-1,y,x,y); if (ok[x+1][y]) dsu.uni(x+1,y,x,y); if (ok[x][y-1]) dsu.uni(x,y-1,x,y); if (ok[x][y+1]) dsu.uni(x,y+1,x,y); ok[x][y]=1; } map<int,int> was; for(auto&it:z) { int x=it/m, y=it%m; int u=dsu.get(it); if (was[u]) continue; was[u]=1; int b=dsu.l[u]; int a=dsu.t[u]; int d=dsu.r[u]; int c=dsu.d[u]; int k=(c-a+1)*(d-b+1); if (k==dsu.sz[u]) ++ans; } } return ans-1; } const int N=700; bitset<N> dp1[N][N], dp2[N][N]; struct BIT { int n,m; vector<vector<int>> t; BIT(int n, int m) { this->n=n, this->m=m; t.assign(n,vector<int>(m,0)); } void addi(int i, int j, int x) { for(;j<m;j=j|(j+1)) t[i][j]+=x; } void add(int i, int j, int x) { for(;i<n;i=i|(i+1)) addi(i,j,x); } int sumi(int i, int j) { int q=0; for(;j>=0;j=(j&(j+1))-1) q+=t[i][j]; return q; } int sum(int a, int b) { int q=0; for(;a>=0;a=(a&(a+1))-1) q+=sumi(a,b); return q; } int sum(int a, int b, int c, int d) { return sum(c,d)-sum(a-1,d)-sum(c,b-1)+sum(a-1,b-1); } }; struct dsu { vector<int> p,sz,l,r; dsu(int n) { forn(i,n) p.pb(i), sz.pb(1); l=r=p; } int get(int u) { return p[u]==u?u:get(p[u]); } void uni(int u, int v) { u=get(u),v=get(v); if (u==v) return; if (sz[u]<sz[v]) swap(u,v); p[v]=u; sz[u]+=sz[v]; l[u]=min(l[u],l[v]); r[u]=max(r[u],r[v]); } }; vector<dsu> dsu1(N,dsu(N)), dsu2(N,dsu(N)); int ok[N][N]; BIT ft(N,N); int a[N][N]; int pre[N+1]; const int K=11; int st1[N][N][K], st2[N][N][K]; void init() { int p=0; forn(i,N+1) { while (2*(1<<p) < i) ++p; pre[i]=p; } } void build(int k, vector<int>&a) { int n=a.size(); forn(i,n) st1[k][i][0]=a[i]; for(int j=1; j<K; ++j) { forn(i,n) st1[k][i][j]=max(st1[k][i][j-1], (i+(1<<(j-1)))<n ? st1[k][i+(1<<(j-1))][j-1] : 0 ); } } inline int query1(int k, int l, int r) { int p=pre[r-l+1]; return max( st1[k][l][p] , st1[k][r-(1<<p)+1][p] ); } inline int query2(int k, int l, int r) { int p=pre[r-l+1]; return max( st2[k][l][p] , st2[k][r-(1<<p)+1][p] ); } int it=0; int check(int l, int u, int r, int d) { int ok=1; for (int i=l; i<=r; ++i) { int x=query1(i,u,d); ok&=a[i][u-1]>x && x<a[i][d+1]; } for (int i=u; i<=d; ++i) { int x=query2(i,l,r); ok&=a[l-1][i]>x && x<a[r+1][i]; } return ok; } ll count_rectangles(vector<vector<int>> b) { int n=b.size(), m=b[0].size(); if (min(n,m)<3) return 0; int mx=0; for(auto&x:b) for(auto&y:x) mx=max(mx,y); if (mx==1) return wrong(b); if (n==3) { ll ans=0; for (int i=0; i<m; ++i) { int mx=0; for (int j=i+1; j<m-1; ++j) { if (b[0][j]<=b[1][j] || b[1][j]>=b[2][j]) break; mx=max(mx,b[1][j]); ans += b[1][i]>mx && mx<b[1][j+1]; } } return ans; } if (max(n,m)>N) exit(0); init(); forn(i,n) forn(j,m) a[i][j]=b[i][j]; forn(i,n) build(i,b[i]); swap(st1,st2); forn(j,m) { vector<int> v; forn(i,n) v.pb(a[i][j]); build(j,v); } swap(st1,st2); vector<pi> v; forn(i,n) forn(j,m) v.pb({a[i][j],i*m+j}); sort(all(v)); ll ans=0; int N=v.size(); map<ll,ll> was; for(int i=0; i<N; ) { vector<int> z; int x=v[i].f; while (i<N && v[i].f==x) { z.pb(v[i].s); ++i; } for(auto&it:z) { int x=it/m, y=it%m; if (x) if (ok[x-1][y]) dsu1[y].uni(x-1,x); if (x<n-1) if (ok[x+1][y]) dsu1[y].uni(x+1,x); if (y) if (ok[x][y-1]) dsu2[x].uni(y-1,y); if (y<m-1) if (ok[x][y+1]) dsu2[x].uni(y+1,y); ok[x][y]=1; ft.add(x,y,1); } for(auto&it:z) { int x=it/m, y=it%m; int u=dsu1[y].get(x); int a=dsu1[y].l[u], c=dsu1[y].r[u]; int v=dsu2[x].get(y); int b=dsu2[x].l[v], d=dsu2[x].r[v]; if (a==0 || b==0 || c==n-1 || d==m-1) continue; if (was[1ll*a*m+b+1ll*n*m*(1ll*c*m+d)]) continue; was[1ll*a*m+b+1ll*n*m*(1ll*c*m+d)]=1; if (it<=0.5e8) { int q = check(a,b,c,d); ans+=q; it+=(c-a+1)+(d-b+1); } else { exit(0); } } } assert(it<=2e8); return ans; }

Compilation message (stderr)

rect.cpp: In function 'long long int wrong(std::vector<std::vector<int> >)':
rect.cpp:79:8: warning: unused variable 'x' [-Wunused-variable]
   79 |    int x=it/m, y=it%m;
      |        ^
rect.cpp:79:16: warning: unused variable 'y' [-Wunused-variable]
   79 |    int x=it/m, y=it%m;
      |                ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...