[关闭]
@xiaoziyao 2021-07-09T20:03:03.000000Z 字数 1198 阅读 991

CF685D Kay and Eternity解题报告

解题报告


CF685D Kay and Eternity解题报告:

更好的阅读体验

题意

网格中有个格子被涂黑,对于 ,求大小为 且能覆盖 个黑色格子的正方形数量。( ,值域范围

分析

考虑答案的范围是很广的,显然不能枚举每个答案并检验其覆盖黑色格子数量。

正难则反,我们发现每个黑色格子 被覆盖当且仅当正方形的右下角在 范围内,也就是在一个以 为左上角,边长为 的正方形内。

问题被转化成对于 ,求有多少个整点被 个矩形覆盖,这是经典问题,扫描线的同时暴力统计一下就好了,复杂度

代码

扫描线注意细节。

  1. #include<stdio.h>
  2. #include<algorithm>
  3. #include<map>
  4. using namespace std;
  5. const int maxn=100005;
  6. int n,k,tot;
  7. int cnt[maxn<<1],num[maxn<<1],val[maxn<<1];
  8. long long ans[maxn];
  9. map<int,int>mp;
  10. struct line{
  11. int x,ya,yb,opt;
  12. }l[maxn<<1];
  13. inline int cmp(line a,line b){
  14. return a.x<b.x;
  15. }
  16. int main(){
  17. scanf("%d%d",&n,&k);
  18. for(int i=1;i<=n;i++){
  19. int a,b;
  20. scanf("%d%d",&a,&b);
  21. l[2*i-1]=line{a,b,b+k-1,1},l[2*i]=line{a+k,b,b+k-1,-1};
  22. num[2*i-1]=b,num[2*i]=b+k;
  23. }
  24. sort(num+1,num+1+2*n),sort(l+1,l+1+2*n,cmp);
  25. for(int i=1;i<=2*n;i++)
  26. if(i==1||num[i]!=num[i-1])
  27. mp[num[i]]=++tot,val[tot]=num[i];
  28. for(int i=1;i<=2*n;i++){
  29. int ya=mp[l[i].ya],yb=mp[l[i].yb+1],opt=l[i].opt,len=l[2*n].x-l[i].x;
  30. for(int j=ya;j<yb;j++){
  31. ans[cnt[j]]-=1ll*len*(val[j+1]-val[j]);
  32. cnt[j]+=opt;
  33. ans[cnt[j]]+=1ll*len*(val[j+1]-val[j]);
  34. }
  35. }
  36. for(int i=1;i<=n;i++)
  37. printf("%lld%c",ans[i],i==n? '\n':' ');
  38. return 0;
  39. }

整场比赛的题解

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注