Submission #1243865

#TimeUsernameProblemLanguageResultExecution timeMemory
1243865hirayuu_ojRectangles (IOI19_rect)C++20
72 / 100
5064 ms846344 KiB
#include "rect.h" #include<bits/stdc++.h> using namespace std; #define rep(i,n) for(int i=0; i<(n); i++) #define all(x) x.begin(),x.end() #define rng(i,l,r) for(int i=(l); i<(r); i++) #define fi first #define se second #define each(i,x) for(auto i:x) using ll=long long; /* #include "grader.cpp" /**/ template<class T,auto op,auto e> struct SegTree{ vector<T> val; int n; SegTree(int sz){ n=sz; val.resize(n*2,e()); } void set(int p,T v){ p+=n; val[p]=v; while(p>1){ p/=2; val[p]=op(val[p*2],val[p*2+1]); } } T prod(int l,int r){ l+=n; r+=n; T rl=e(),rr=e(); while(l<r){ if(l&1){ rl=op(rl,val[l]);l++; } if(r&1){ r--;rr=op(val[r],rr); } l/=2;r/=2; } return op(rl,rr); } }; ll mn(ll x,ll y){return min(x,y);} ll mx(ll x,ll y){return max(x,y);} ll emn(){ return 1LL<<60; } ll emx(){ return -(1LL<<60); } using seg=pair<int,int>; int num(seg sm){ return sm.fi*2502+sm.se; } ll rc_num(seg r,seg c){ return num(r)*998244353LL+num(c); } const int X=2510*2510; long long count_rectangles(std::vector<std::vector<int> > a) { int n=a.size();int m=a[0].size(); vector<vector<seg>> r(n,vector<seg>(m,{-1,-1})); vector<vector<seg>> c(n,vector<seg>(m,{-1,-1})); rep(i,n){ vector<pair<int,int>> pos(m); rep(j,m){ pos[j]={a[i][j],j}; } sort(all(pos)),reverse(all(pos)); SegTree<ll,mn,emn> rmq(m); SegTree<ll,mx,emx> rMq(m); int cnt=0; rep(j,m){ while(pos[j].fi!=pos[cnt].fi){ rmq.set(pos[cnt].se,pos[cnt].se); rMq.set(pos[cnt].se,pos[cnt].se); cnt++; } ll lf=rMq.prod(0,pos[j].se); ll ri=rmq.prod(pos[j].se,m); if(lf<0||ri>m)continue; r[i][pos[j].se]={lf+1,ri}; } } rep(i,m){ vector<pair<int,int>> pos(n); rep(j,n){ pos[j]={a[j][i],j}; } sort(all(pos)),reverse(all(pos)); SegTree<ll,mn,emn> rmq(n); SegTree<ll,mx,emx> rMq(n); int cnt=0; rep(j,n){ while(pos[j].fi!=pos[cnt].fi){ rmq.set(pos[cnt].se,pos[cnt].se); rMq.set(pos[cnt].se,pos[cnt].se); cnt++; } ll lf=rMq.prod(0,pos[j].se); ll ri=rmq.prod(pos[j].se,n); if(lf<0||ri>n)continue; c[pos[j].se][i]={lf+1,ri}; } } unordered_set<ll> cand; vector<vector<int>> rr(X); rep(i,n){ rep(j,m){ if(r[i][j].fi!=-1&&(rr[num(r[i][j])].empty()||rr[num(r[i][j])].back()!=i)){ rr[num(r[i][j])].push_back(i); } } } vector<vector<int>> cc(X); rep(i,m){ rep(j,n){ if(c[j][i].fi!=-1&&(cc[num(c[j][i])].empty()||cc[num(c[j][i])].back()!=i)){ cc[num(c[j][i])].push_back(i); } } } ll ret=0; rep(i,n){ rep(j,m){ if(r[i][j].fi!=-1&&c[i][j].fi!=-1){ ll nm=rc_num(r[i][j],c[i][j]); if(!cand.count(nm)){ cand.insert(nm); int m1=lower_bound(all(cc[num(c[i][j])]),r[i][j].fi)-cc[num(c[i][j])].begin(); int m2=lower_bound(all(cc[num(c[i][j])]),r[i][j].se)-cc[num(c[i][j])].begin(); if(r[i][j].se-r[i][j].fi!=m2-m1)continue; m1=lower_bound(all(rr[num(r[i][j])]),c[i][j].fi)-rr[num(r[i][j])].begin(); m2=lower_bound(all(rr[num(r[i][j])]),c[i][j].se)-rr[num(r[i][j])].begin(); if(c[i][j].se-c[i][j].fi!=m2-m1)continue; ret++; } } } } /* */ return ret; }
#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...