周賽D. Digging for Gold(掃描線)
阿新 • • 發佈:2021-11-10
給出二維平面上的一些點。
詢問一個\(K\times K\)的正方形,最多能覆蓋多少點。
做法:
考慮這個正方形的一個角。這個角確定了,正方形也就確定了。
對於一個點,合法的角的座標範圍形成了一個矩形。
問題轉化為,求一些矩形的最大重合點是多少。
掃描線即可。
時間複雜度O(nlogn)。
//對一個點(x,y)來說 //一個矩形內的點是合法的 //那就二維差分 // //對每個(x,y)對應一個矩形 //求這些矩形的最大覆蓋點 //用掃描線 #include<bits/stdc++.h> using namespace std; const int maxn=1e6+10; int n,m,k; int t[maxn],mm; struct { pair<int,int> p[4]; //e表示矩形的長 }jx[maxn]; struct qnode { int l,r,v; }; vector<qnode> g[maxn]; int c[maxn<<2],lz[maxn<<2]; void pushdown (int i,int l,int r) { int mid=(l+r)>>1; if (lz[i]) { c[i<<1]+=lz[i]; lz[i<<1]+=lz[i]; c[i<<1|1]+=lz[i]; lz[i<<1|1]+=lz[i]; lz[i]=0; } } void up (int i,int l,int r,int L,int R,int v) { if (l>=L&&r<=R) { c[i]+=v; lz[i]+=v; return; } pushdown(i,l,r); int mid=(l+r)>>1; if (L<=mid) up(i<<1,l,mid,L,R,v); if (R>mid) up(i<<1|1,mid+1,r,L,R,v); c[i]=max(c[i<<1],c[i<<1|1]); } map<pair<int,int> ,int> mp; int gg[200][200]; int main () { scanf("%d%d%d",&n,&m,&k); if (k==1) { int ans=0; while (m--) { int x,y; scanf("%d%d",&x,&y); mp[{x,y}]++; ans=max(ans,mp[{x,y}]); } printf("%d\n",ans); return 0; } for (int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); jx[i].p[0]={x-k+1,y-k+1}; jx[i].p[1]={x,y-k+1}; jx[i].p[2]={x,y}; jx[i].p[3]={x-k+1,y}; for (int j=0;j<4;j++) { //printf("%d: %d %d\n",i,jx[i].p[j].first,jx[i].p[j].second); t[++mm]=jx[i].p[j].first; t[++mm]=jx[i].p[j].second; } } sort(t+1,t+mm+1); mm=unique(t+1,t+mm+1)-t-1; for (int i=1;i<=m;i++) { for (int j=0;j<4;j++) { jx[i].p[j].first=upper_bound(t+1,t+mm+1,jx[i].p[j].first)-t-1; jx[i].p[j].second=upper_bound(t+1,t+mm+1,jx[i].p[j].second)-t-1; } // for (int j=jx[i].p[0].first;j<=jx[i].p[1].first;j++) { // for (int kk=jx[i].p[0].second;kk<=jx[i].p[2].second;kk++) { // gg[j][kk]++; // } // } } // for (int i=1;i<=mm;i++) { // for (int j=1;j<=mm;j++) { // printf("%d ",gg[i][j]); // } // puts(""); // } // return 0; for (int i=1;i<=m;i++) { g[jx[i].p[0].first].push_back({jx[i].p[0].second,jx[i].p[3].second,1}); g[jx[i].p[1].first+1].push_back({jx[i].p[1].second,jx[i].p[2].second,-1}); } int ans=0; for (int i=1;i<=mm;i++) { for (qnode it:g[i]) { int l=it.l; int r=it.r; int v=it.v; //printf("%d %d %d %d\n",i,l,r,v); up(1,1,mm,l,r,v); } //printf("%d\n",c[1]); ans=max(ans,c[1]); } printf("%d\n",ans); } /* 1000000000 4 1000000000 1000000000 1000000000 1000000000 1 1 1000000000 1 1 */