zoukankan      html  css  js  c++  java
  • 周赛D. Digging for Gold(扫描线)

    给出二维平面上的一些点。

    询问一个\(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
    */
  • 相关阅读:
    17963 完美数
    17086 字典序的全排列
    17082 两个有序数序列中找第k小(优先做)
    11087 统计逆序对(优先做)
    8594 有重复元素的排列问题(优先做)
    11076 浮点数的分数表达(优先做)
    9715 相邻最大矩形面积
    剑指offer----替换空格
    [IIS][ASP.NET]“拒绝访问临时目录”的解决方法
    windows 2003端口80system进程占用的情况
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/15531243.html
Copyright © 2011-2022 走看看