Submission #1212516

#TimeUsernameProblemLanguageResultExecution timeMemory
1212516loiiii12358Rectangles (IOI19_rect)C++20
10 / 100
1043 ms1114112 KiB
#include "rect.h" #include <bits/stdc++.h> using namespace std; struct coor{ short r,c; coor(){ r=c=0; } coor(short x,short y){ r=x;c=y; } }; struct segment{ short r,R,c,C; segment(){ r=c=-1;R=C=8192; } segment(short x,short X,short y,short Y){ r=x;R=X;c=y;C=Y; } }; vector<set<short>> rowset,colset; vector<vector<coor>> countvec; vector<pair<int,coor>> vec; vector<vector<segment>> grid; vector<segment> seg; segment merge(segment a,segment b){ segment ans; ans.r=min(a.r,b.r); ans.c=min(a.c,b.c); ans.R=max(a.R,b.R); ans.C=max(a.C,b.C); return ans; } void build(int id,coor l,coor r){ if(l.r==r.r){ seg[id]=grid[l.r][l.c]; return; } coor m=coor((l.r+r.r)/2,(l.c+r.c)/2); build(id*4,l,m); build(id*4+1,coor(m.r+1,l.c),coor(r.r,m.c)); build(id*4+2,coor(l.r,m.c+1),coor(m.r,r.c)); build(id*4+3,coor(m.r+1,m.c+1),r); seg[id]=merge(merge(seg[id*4],seg[id*4+1]),merge(seg[id*4+2],seg[id*4+3])); } void update(int id,coor l,coor r,coor x,segment c){ if(l.r==r.r){ seg[id]=c; return; } coor m=coor((l.r+r.r)/2,(l.c+r.c)/2); if(x.r<=m.r){ if(x.c<=m.c){ update(id*4,l,m,x,c); seg[id]=merge(seg[id],seg[id*4]); }else{ update(id*4+2,coor(l.r,m.c+1),coor(m.r,r.c),x,c); seg[id]=merge(seg[id],seg[id*4+2]); } }else if(x.c<=m.c){ update(id*4+1,coor(m.r+1,l.c),coor(r.r,m.c),x,c); seg[id]=merge(seg[id],seg[id*4+1]); }else{ update(id*4+3,coor(m.r+1,m.c+1),r,x,c); seg[id]=merge(seg[id],seg[id*4+3]); } } segment query(int id,coor l,coor r,coor L,coor R){ if(r.r<L.r||r.c<L.c||l.r>R.r||l.c>R.c){ return segment(8192,-1,8192,-1); }else if(l.r>=L.r&&l.c>=L.c&&r.r<=R.r&&r.c<=R.c){ return seg[id]; } coor m=coor((l.r+r.r)/2,(l.c+r.c)/2); return merge(merge(query(id*4,l,m,L,R),query(id*4+1,coor(m.r+1,l.c),coor(r.r,m.c),L,R)),merge(query(id*4+2,coor(l.r,m.c+1),coor(m.r,r.c),L,R),query(id*4+3,coor(m.r+1,m.c+1),r,L,R))); } //8000*8000->128MB*4->512MB //100MB long long count_rectangles(vector<vector<int> > a) { int n=a.size(),m=a[0].size(); long long ans=0; vec.resize(n*m);countvec.resize(7000009);rowset.resize(n);colset.resize(m);seg.resize(8200*8200); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ vec[i*m+j]={a[i][j],coor(i,j)}; countvec[a[i][j]].push_back(coor(i,j)); rowset[i].insert(j); colset[j].insert(i); } } sort(vec.begin(),vec.end(),[](pair<int,coor> A,pair<int,coor> B){ return A.first<B.first; }); grid.resize(4100,vector<segment>(4100,segment())); build(1,coor(0,0),coor(4095,4095)); for(int i=0;i<n*m;i++){ int r=vec[i].second.r,c=vec[i].second.c; for(auto u:countvec[a[r][c]]){ rowset[u.r].erase(u.c); colset[u.c].erase(u.r); } countvec[a[r][c]].clear(); auto u=colset[c].lower_bound(r); if(u==colset[c].end()){ grid[r][c].R=n-1; }else{ grid[r][c].R=(*u)-1; } if(u==colset[c].begin()){ grid[r][c].r=0; }else{ grid[r][c].r=(*--u)+1; } u=rowset[r].lower_bound(c); if(u==rowset[r].end()){ grid[r][c].C=m-1; }else{ grid[r][c].C=(*u)-1; } if(u==rowset[r].begin()){ grid[r][c].c=0; }else{ grid[r][c].c=(*--u)+1; } update(1,coor(0,0),coor(4095,4095),coor(r,c),grid[r][c]); bool can=(grid[r][c].r>0&&grid[r][c].R<n-1&&grid[r][c].c>0&&grid[r][c].C<m-1); if(can){ segment tmp=query(1,coor(0,0),coor(4095,4095),coor(grid[r][c].r,grid[r][c].c),coor(grid[r][c].R,grid[r][c].C)); if(tmp.r>=grid[r][c].r&&tmp.c>=grid[r][c].c&&tmp.R<=grid[r][c].R&&tmp.C<=grid[r][c].C){ ans++; } } } 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...