HDU5126---stars (CDQ套CDQ套 树状数组)

题意:Q次操作,三维空间内 每个星星对应一个坐标,查询以(x1,y1,z1) (x2,y2,z2)为左下顶点 、右上顶点的立方体内的星星的个数。

注意Q的范围为50000,显然离散化之后用三维BIT会MLE。 我们可以用一次CDQ把三维变成二维,变成二维之后就有很多做法了,树套树,不会树套树的话还可以继续CDQ由二维变成一维,,变成一维了就好做了,,最基本的数据结构题目了。。

不得不说、CDQ真的很神奇。

下面做法就是CDQ套CDQ套树状数组。

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <algorithm>
  5 using namespace std;
  6 const int maxn = 50010;
  7 inline int lowbit (int x)
  8 {
  9     return x & -x;
 10 }
 11 int c[maxn*9],MAX;
 12 void add(int x,int d)
 13 {
 14     while (x <= MAX)
 15     {
 16         c[x] += d;
 17         x += lowbit(x);
 18     }
 19 }
 20 int sum(int x)
 21 {
 22     int ans = 0;
 23     while (x)
 24     {
 25         ans += c[x];
 26         x -= lowbit (x);
 27     }
 28     return ans;
 29 }
 30 struct Point
 31 {
 32     int x,y,z;
 33     int kind,idx,delt;
 34     Point() {}
 35     Point(int _x,int _y,int _z,int _delt,int _kind,int _idx):
 36         x(_x), y(_y), z(_z), delt(_delt), kind(_kind), idx(_idx) {}
 37 
 38 } star[maxn << 4],star3[maxn << 4];
 39 int ans[maxn<<1];
 40 bool cmp1(const Point &p1,const Point &p2)
 41 {
 42     return p1.x < p2.x || ((p1.x == p2.x) && (p1.idx < p2.idx) );
 43 }
 44 bool cmp2(const Point &p1,const Point &p2)
 45 {
 46     return p1.y < p2.y || ((p1.y == p2.y) && (p1.idx < p2.idx) );
 47 }
 48 void CDQ2(int l,int r)
 49 {
 50     if (l >= r)
 51         return;
 52     int mid = (l + r) >> 1;
 53     CDQ2(l,mid);
 54     CDQ2(mid+1,r);
 55     int j = l;
 56     for (int i = mid + 1; i <= r; i++)
 57     {
 58         if (star3[i].kind == 1)
 59         {
 60             for ( ; j <= mid  && (star3[j].y <= star3[i].y); j++)
 61             {
 62                 if (star3[j].kind == 0)
 63                     add(star3[j].z,star3[j].delt);
 64             }
 65             ans[star3[i].idx] += sum(star3[i].z) * star3[i].delt;
 66         }
 67     }
 68     for (int i = l; i < j; i++)
 69     {
 70         if (star3[i].kind == 0)
 71             add(star3[i].z,-star3[i].delt);
 72     }
 73     inplace_merge(star3+l,star3+mid+1,star3+r+1,cmp2);
 74 }
 75 void CDQ1(int l,int r)
 76 {
 77     if (l == r)
 78         return;
 79     int mid = (l + r) >> 1;
 80     CDQ1(l, mid);
 81     CDQ1(mid+1, r);
 82     int tot = 1;
 83     for (int j = l; j <= mid ; j++)
 84         if (star[j].kind == 0)
 85             star3[tot++] = star[j];
 86     for (int i = mid + 1; i <= r; i++)
 87     {
 88         if (star[i].kind == 1)
 89             star3[tot++] = star[i];
 90     }
 91     sort(star3+1,star3+tot,cmp1);
 92     CDQ2(1,tot-1);
 93 }
 94 int vec[maxn << 4],idx;
 95 void hash_(int tot)
 96 {
 97     sort(vec,vec+idx);
 98     idx = unique(vec,vec+idx) - vec;
 99     MAX = idx + 1;
100     for (int i = 1; i <= tot; i++)
101         star[i].z = lower_bound(vec,vec+idx,star[i].z) - vec + 1;
102 }
103 int main(void)
104 {
105 #ifndef ONLINE_JUDGE
106     freopen("in.txt","r",stdin);
107 #endif // ONLINE_JUDGE
108     int T,Q;
109     scanf ("%d",&T);
110     while (T--)
111     {
112         scanf ("%d",&Q);
113         int tot = 1;
114         int totq = 0;
115         idx = 0;
116         memset(c,0,sizeof (c));
117         memset(ans,0,sizeof(ans));
118         for (int i = 1; i <= Q; i++)
119         {
120             int op,x1,y1,z1,x2,y2,z2;
121             scanf ("%d",&op);
122             if (op == 1)
123             {
124                 scanf ("%d%d%d",&x1,&y1,&z1);
125                 star[tot] = Point(x1,y1,z1,1,0,totq);
126                 vec[idx++] = z1;
127                 ans[totq] = -1;
128                 tot++;
129                 totq++;
130             }
131             if (op == 2)
132             {
133                 scanf ("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2);
134                 star[tot] = Point(x1-1, y1-1, z1-1, -1, 1, totq),  vec[idx++] = z1-1, tot++;
135                 star[tot] = Point(x2,   y1-1, z1-1,  1, 1, totq),  vec[idx++] = z1-1, tot++;
136                 star[tot] = Point(x2 ,  y2  , z1-1, -1, 1, totq),  vec[idx++] = z1-1, tot++;
137                 star[tot] = Point(x1-1, y2,   z1-1,  1, 1, totq),  vec[idx++] = z1-1, tot++;
138                 star[tot] = Point(x1-1, y2,   z2  , -1, 1, totq),  vec[idx++] = z2  , tot++;
139                 star[tot] = Point(x2  , y2,   z2  ,  1, 1, totq),  vec[idx++] = z2  , tot++;
140                 star[tot] = Point(x2  , y1-1, z2  , -1, 1, totq),  vec[idx++] = z2  , tot++;
141                 star[tot] = Point(x1-1, y1-1, z2  ,  1, 1, totq),  vec[idx++] = z2  , tot++;
142                 totq++;
143             }
144         }
145         hash_(tot);
146         CDQ1(1,tot-1);
147         for (int i = 0; i < totq; i++)
148             if (~ans[i])
149                 printf("%d
",ans[i]);
150     }
151     return 0;
152 }
原文地址:https://www.cnblogs.com/oneshot/p/4154040.html