zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    关于json中对象的删除
    JDBC操作数据库 封装好的工具类
    json <--->List集合,实体类 之间的相互转换
    java--->>发送邮件
    登陆的过滤器
    Hadoop + Spark 在CentOS下的伪分布式部署
    CentOS和ubuntu修改hostname的区别
    ubuntu 用户管理 adduser vs useradd
    hadoop2.6.1源码编译64位
    MySQL Binlog详解
  • 原文地址:https://www.cnblogs.com/oneshot/p/4154040.html
Copyright © 2011-2022 走看看