Codeforces Round #359 (Div. 1) D. Kay and Eternity ★ ★ ★ ★

来源:互联网 发布:交通银行数据录入员 编辑:程序博客网 时间:2024/06/05 16:09

题意:给定n(1e5)个点,分别包含1,2,3,.......n个点的k*k(300)的矩阵各有多少个。

题解:首先对 yy 离散化。把每个矩形看作在 xx 进入,在 (x+k)(x+k) 退出。
我们维护 count[y] 表示 yy 点现在被覆盖的次数,那么每次事件是把 [y, y + k)[y,y+k) 的 count 加一(或者减一)。
只要在 count 变化的时候,把变化前的值计入答案即可。

#include <map>#include <set>#include <cmath>#include <ctime>#include <cstdio>#include <vector>#include <cstring>#include <cstdlib>#include <algorithm>using namespace std;#define mp make_pair#define pb push_back#define x first#define y secondtypedef long long ll;typedef vector<int> vi;typedef pair<int,int> pii;typedef vector<pii> vpii;const int N=100010;struct point{int x,y;bool operator <(point a)const {return y<a.y;}}a[N];int b[2*N],d[N];ll ans[N];vi c[2*N];int main(){#ifndef ONLINE_JUDGEfreopen("input.txt","r",stdin);freopen("output.txt","w",stdout);#endifint n,k;scanf("%d%d",&n,&k);for (int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);sort(a+1,a+n+1);for (int i=1;i<=n;i++) {b[2*i-1]=a[i].x;b[2*i]=a[i].x+k;}sort(b+1,b+2*n+1);int m=1;for (int i=2;i<=2*n;i++) if (b[i]!=b[i-1]) b[++m]=b[i];for (int i=1;i<=n;i++){int l=lower_bound(b+1,b+m+1,a[i].x)-b,r=lower_bound(b+1,b+m+1,a[i].x+k)-b;for (int j=l;j<r;j++) c[j].pb(i);}for (int i=1;i<m;i++){int l=0;for (vi::iterator p=c[i].begin();p!=c[i].end();p++) d[++l]=*p;int p=1;for (int j=2;j<=l+1;j++){int pre=a[d[j-1]].y;while (p<j&&(j==l+1||a[d[p]].y+k<=a[d[j]].y)){ans[j-p]+=ll(b[i+1]-b[i])*(a[d[p]].y+k-pre);pre=a[d[p]].y+k;p++;}ans[j-p]+=ll(b[i+1]-b[i])*(a[d[j]].y-pre);}}for (int i=1;i<=n;i++) printf("%I64d ",ans[i]);return 0;}


0 0
原创粉丝点击