Submission #348125

#TimeUsernameProblemLanguageResultExecution timeMemory
348125KerimRectangles (IOI19_rect)C++17
100 / 100
4513 ms650252 KiB
#include "rect.h" #include "bits/stdc++.h" #define MAXN 100009 #define INF 1000000007 #define mp(x,y) make_pair(x,y) #define all(v) v.begin(),v.end() #define pb(x) push_back(x) #define wr cout<<"----------------"<<endl; #define ppb() pop_back() #define tr(ii,c) for(__typeof((c).begin()) ii=(c).begin();ii!=(c).end();ii++) #define ff first #define ss second #define my_little_dodge 46 #define debug(x,y,z) cerr<< #x <<" = "<< x<<" "<< #y <<" = "<< y<<" "<< #z <<" = "<< z<<endl; using namespace std; typedef long long ll; typedef pair<int,int> PII; template<class T>bool umin(T& a,T b){if(a>b){a=b;return 1;}return 0;} template<class T>bool umax(T& a,T b){if(a<b){a=b;return 1;}return 0;} const int N=2505; int ata[N],mn[N],mx[N],arr[N],c[N],sz,sub[N],vis[N],rc,pos; vector<int>row[N][N],col[N][N]; vector<pair<PII,int> >addc[N]; vector<PII>remc[N]; int F[N][N]; bool cmp(int x,int y){ return (arr[x]<arr[y]); } int tap(int x){ if(ata[x]==x)return x; return ata[x]=tap(ata[x]); } void merge(int x,int y){ if((x=tap(x))==(y=tap(y)))return; if(sub[x]<sub[y])swap(x,y); ata[y]=x;sub[x]+=sub[y]; umin(mn[x],mn[y]); umax(mx[x],mx[y]); } //The key idea is there are at most 2*n^2 such pairs void add(int x,int y){ assert(x+1<y); //if rc=0, then rectangle on row (pos) in range (arr[pos][x],arr[pos][y]) is good //if rc=1, then rectangle on column (pos) in range (arr[x][pos],arr[y][pos]) is good if(!rc)row[x][y].pb(pos); else col[x][y].pb(pos); } void solve(int x){ if(x>1 and vis[x-1]){ int a=mn[tap(x-1)]-1; if(a>=1)add(a,x); } if(x<sz and vis[x+1]){ int b=mx[tap(x+1)]+1; if(b<=sz)add(x,b); } } void upd(int x){ vis[x]=1; if(x>1 and vis[x-1])merge(x-1,x); if(x<sz and vis[x+1])merge(x,x+1); } void f(){ for(int i=1;i<=sz;i++) ata[i]=mn[i]=mx[i]=i,sub[i]=1,c[i]=i,vis[i]=0; sort(c+1,c+sz+1,cmp); for(int i=1;i<=sz;i++){ int j=i; while(j<=sz and arr[c[j]]==arr[c[i]])solve(c[j++]); for(int k=i;k<j;k++)upd(c[k]); i=j-1; } } void upd(int y,int x,int val){ for(;x<N;x+=x&(-x))F[y][x]+=val; } int get(int y,int x){ int res=0; for(;x;x-=x&(-x))res+=F[y][x]; return res; } void relax(int tt,int x,int y){ if(!tt) row[x][y].erase(unique(all(row[x][y])),row[x][y].end()); else col[x][y].erase(unique(all(col[x][y])),col[x][y].end()); } long long count_rectangles(std::vector<std::vector<int> > a) { int n=int(a.size()),m=int(a[0].size()); if(n<3 or m<3) return 0; { sz=m; for(int j=1;j<=n;j++){ for(int i=1;i<=m;i++) arr[i]=a[j-1][i-1]; rc=0;pos=j;f(); }sz=n; for(int j=1;j<=m;j++){ for(int i=1;i<=n;i++) arr[i]=a[i-1][j-1]; rc=1;pos=j;f(); } } int tmp,st=-1,en,cnt,who; for(int i=1;i<=n;i++) for(int j=i+2;j<=n;j++){ relax(1,i,j); tmp=int(col[i][j].size()); for(int k=0;k<tmp;k++){ if(st==-1)st=col[i][j][k]; en=col[i][j][k]; if(k+1==tmp or col[i][j][k]+1!=col[i][j][k+1]){ for(int h=st;h<=en;h++) addc[h].pb(mp(mp(i+1,j-1),en)); st=-1; } } } ll ans=0; for(int i=2;i<m;i++){ tr(it,addc[i])upd(it->ff.ss,it->ff.ff,+1),remc[it->ss].pb(it->ff); addc[i].clear(); for(int j=i;j<=m;j++){ if(j<m){ relax(0,i-1,j+1); tmp=int(row[i-1][j+1].size());cnt=0; for(int k=0;k<tmp;k++){who=row[i-1][j+1][k]; cnt++;ans+=get(who,who)-get(who,who-cnt); if(k+1==tmp or who+1!=row[i-1][j+1][k+1])cnt=0; } } tr(it,remc[j])upd(it->ss,it->ff,-1); remc[j].clear(); } } return ans; }
#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...