[关闭]
@y20070316 2017-04-27T02:44:17.000000Z 字数 3328 阅读 887

XSY 2060 - Rectangle Query

题目精选 压位


题意

  平面内给定 个点 。给定 个询问,询问 以 为左下角, 为右上角的矩形内,不同的横坐标和不同的纵坐标分别有多少个。
   ,强制在线

分析

  对每一个点 ,我们用一个四元组 进行刻画。
   表示它的横坐标, 表示它的纵坐标, 表示与它相同的纵坐标的上一个横坐标, 表示与它相同的横坐标的上一个纵坐标。
  那么,一个矩形 中的不同横坐标的个数,就是满足


的点 的个数。
  纵坐标也类似,这里不展开讨论。

  我们在处理这种满足多个条件的问题时,一种想法就是先满足一个条件,然后再满足一个条件,对应着树套树、cdq分治等方法;还有一种想法就是分别求满足这几个条件的,然后合并起来。
  至于合并的方法就比较暴力了,我们考虑使用 bitset 进行优化。
  而且这道题的数据范围是 ,一般这种复杂度都是进行一些 或者 或者 这种没有 优的方法。

  所以这道题,我们考虑对每个限制条件开 bitset ,表示 的满足的位置。那么,预处理的时间复杂度为 ,空间为 。查询的时间为 。然而发现这样会爆空间。

  我们考虑使用时间换空间。我们对每个限制条件开 bitset ,每个存 的满足的位置。那么,预处理的时间为 ,空间为 。查询的时间为

实现

   bitset<N> 的空间估计:一个 long long 位,所以共存了 位,所以空间为
   bitset<N> 的一些必须知道的功能: reset() flip() set() count()

  一种简易的离散化的写法:不需要 unique 即可。

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cctype>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <vector>
  7. #include <bitset>
  8. using namespace std;
  9. #define F(i,a,b) for (int i=(a);i<=(b);i++)
  10. #define X first
  11. #define Y second
  12. const int N=50005;
  13. const int B=250;
  14. const int RNF=-(~0u>>1);
  15. const int INF=~0u>>1;
  16. int online;
  17. int n; pair<int,int> p[N];
  18. int hx[N],hy[N];
  19. int c,tot;
  20. vector< pair<int,int> > vec[N];
  21. struct BIT {
  22. pair<int,int> p[N];
  23. bitset<N> bit[B];
  24. void Init(void) {
  25. sort(p+1,p+n+1);
  26. F(i,1,n) F(j,(i+c-1)/c,tot)
  27. bit[j][p[i].Y]=1;
  28. }
  29. bitset<N> Get(int x) {
  30. bitset<N> ret;
  31. int loc=lower_bound(p+1,p+n+1,make_pair(x,INF))-p-1;
  32. if (!loc) return ret.reset(),ret;
  33. int b=(loc+c-1)/c; ret=bit[b-1]; F(i,(b-1)*c+1,loc) ret[p[i].Y]=1;
  34. return ret;
  35. }
  36. bitset<N> Query(int l,int r) {
  37. return Get(r)^Get(l-1);
  38. }
  39. }g[4];
  40. int m;
  41. inline int rd(void) {
  42. int x=0,f=1; char c=getchar();
  43. for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
  44. for (;isdigit(c);c=getchar()) x=x*10+c-'0';
  45. return x*f;
  46. }
  47. inline void decode(int &x1,int &y1,int &x2,int &y2,int ansx,int ansy) {
  48. x1+=online*(ansx+ansy); y1+=online*(ansx+ansy); x2+=online*(ansx+ansy); y2+=online*(ansx+ansy);
  49. x1=lower_bound(hx+1,hx+n+1,x1)-hx;
  50. y1=lower_bound(hy+1,hy+n+1,y1)-hy;
  51. x2=upper_bound(hx+1,hx+n+1,x2)-hx-1;
  52. y2=upper_bound(hy+1,hy+n+1,y2)-hy-1;
  53. }
  54. int main(void) {
  55. #ifndef ONLINE_JUDGE
  56. freopen("sdchr.in","r",stdin);
  57. freopen("sdchr.out","w",stdout);
  58. #endif
  59. cin>>online;
  60. cin>>n; F(i,1,n) p[i].X=rd(),p[i].Y=rd();
  61. F(i,1,n) hx[i]=p[i].X; sort(hx+1,hx+n+1); F(i,1,n) p[i].X=lower_bound(hx+1,hx+n+1,p[i].X)-hx;
  62. F(i,1,n) hy[i]=p[i].Y; sort(hy+1,hy+n+1); F(i,1,n) p[i].Y=lower_bound(hy+1,hy+n+1,p[i].Y)-hy;
  63. c=(int)sqrt(n); tot=(n+c-1)/c;
  64. F(i,1,n) g[0].p[i]=make_pair(p[i].X,i),g[1].p[i]=make_pair(p[i].Y,i);
  65. g[0].Init(); g[1].Init();
  66. int ind=0;
  67. F(i,1,n) vec[p[i].X].push_back(make_pair(p[i].Y,i));
  68. F(i,1,n) if (vec[i].size()>0) {
  69. sort(vec[i].begin(),vec[i].end());
  70. F(j,0,vec[i].size()-1)
  71. g[2].p[++ind]=make_pair(j>0?vec[i][j-1].X:0,vec[i][j].Y);
  72. vec[i].clear();
  73. }
  74. g[2].Init();
  75. ind=0;
  76. F(i,1,n) vec[p[i].Y].push_back(make_pair(p[i].X,i));
  77. F(i,1,n) if (vec[i].size()>0) {
  78. sort(vec[i].begin(),vec[i].end());
  79. F(j,0,vec[i].size()-1)
  80. g[3].p[++ind]=make_pair(j>0?vec[i][j-1].X:0,vec[i][j].Y);
  81. vec[i].clear();
  82. }
  83. g[3].Init();
  84. int ansx=0,ansy=0; cin>>m;
  85. F(c,1,m) {
  86. int x1=rd(),y1=rd(),x2=rd(),y2=rd();
  87. decode(x1,y1,x2,y2,ansx,ansy);
  88. bitset<N> t=g[0].Query(x1,x2)&g[1].Query(y1,y2);
  89. ansx=(t&g[2].Get(y1-1)).count();
  90. ansy=(t&g[3].Get(x1-1)).count();
  91. printf("%d %d\n",ansx,ansy);
  92. }
  93. return 0;
  94. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注