zoukankan      html  css  js  c++  java
  • HDU5126 stars(CDQ分治)

    传送门

    大意:

    向三维空间中加点,询问一个三维区间中点的个数。

    解题思路:

    带修改CDQ,将修改和询问一起插入CDQ分治询问。

    (询问可以由8个前缀和加减操作实现)

    其中第一层CDQ维护x有序。

    第二层CDQ维护y有序并且将z离线处理完更新答案。

    注意要将原数组的辅助数组推入第二层CDQ否则会将顺序毁坏。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 const int N=1000001;
      5 const int M=4000001;
      6 struct data{
      7     int t;
      8     int x;
      9     int y;
     10     int tz;
     11     int z;
     12     int c;
     13     bool left;
     14 }d[N],o[N],tmp[N],stdata;
     15 int n,T;
     16 int cnt;
     17 int tot;
     18 int ans[N];
     19 int sek[N];
     20 int line[M];
     21 bool cmpz(data a,data b){return a.tz<b.tz;}
     22 bool cmpb(data a,data b){return a.t<b.t;}
     23 int lowbit(int x){return x&(-x);}
     24 void update(int pos,int v)
     25 {
     26     while(pos<=tot)
     27     {
     28         line[pos]+=v;
     29         pos+=lowbit(pos);
     30     }
     31     return ;
     32 }
     33 int query(int pos)
     34 {
     35     int ans=0;
     36     while(pos)
     37     {
     38         ans+=line[pos];
     39         pos-=lowbit(pos);
     40     }
     41     return ans;
     42 }
     43 void Get(void)
     44 {
     45     tot=1;
     46     std::sort(d+1,d+cnt+1,cmpz);
     47     d[1].z=1;
     48     for(int i=2;i<=cnt;i++)
     49     {
     50         if(d[i].tz!=d[i-1].tz)
     51             tot++;
     52         d[i].z=tot;
     53     }
     54     std::sort(d+1,d+cnt+1,cmpb);
     55     return ;
     56 }
     57 void cdq(int l,int r)
     58 {
     59     if(l==r)
     60         return ;
     61     int mid=(l+r)>>1;
     62     cdq(l,mid);
     63     cdq(mid+1,r);
     64     int j=l;
     65     for(int i=mid+1;i<=r;i++)
     66     {
     67         for(;j<=mid&&o[j].y<=o[i].y;j++)
     68             if(!o[j].c&&o[j].left)
     69                 update(o[j].z,1);
     70         if(o[i].left)
     71             continue;
     72         ans[o[i].t]+=o[i].c*query(o[i].z);
     73     }
     74     for(int i=l;i<j;i++)
     75         if(!o[i].c&&o[i].left)
     76             update(o[i].z,-1);
     77     int sta1=l,sta2=mid+1;
     78     for(int i=l;i<=r;i++)
     79         if(sta1<=mid&&(sta2>r||o[sta1].y<=o[sta2].y))
     80             tmp[i]=o[sta1++];
     81         else
     82             tmp[i]=o[sta2++];
     83     for(int i=l;i<=r;i++)
     84         o[i]=tmp[i];
     85     return ;
     86 }
     87 void CDQ(int l,int r)
     88 {
     89     if(l==r)
     90         return ;
     91     int mid=(l+r)>>1;
     92     CDQ(l,mid);
     93     CDQ(mid+1,r);
     94     for(int i=l;i<=r;i++)
     95         d[i].left=(i<=mid);
     96     int sta1=l,sta2=mid+1;
     97     for(int i=l;i<=r;i++)
     98         if(sta1<=mid&&(sta2>r||d[sta1].x<=d[sta2].x))
     99             o[i]=d[sta1++];
    100         else
    101             o[i]=d[sta2++];
    102     for(int i=l;i<=r;i++)
    103         d[i]=o[i];
    104     cdq(l,r);
    105     for(int i=l;i<=r;i++)
    106         d[i].left=false;
    107     return ;
    108 }
    109 int main()
    110 {
    111     //freopen("a.in","r",stdin);
    112     scanf("%d",&T);
    113     while(T--)
    114     {
    115         for(int i=1;i<=n;i++)
    116             ans[i]=0;
    117         for(int i=1;i<=cnt;i++)
    118             d[i]=tmp[i]=stdata;
    119         cnt=n=0;
    120         scanf("%d",&n);
    121         for(int i=1;i<=n;i++)
    122         {
    123             int cmd;
    124             scanf("%d",&cmd);
    125             sek[i]=cmd;
    126             if(cmd==1)
    127             {
    128                 int x,y,z;
    129                 scanf("%d%d%d",&x,&y,&z);
    130                 d[++cnt]=(data){i,x,y,z,0,0,0};
    131             }else{
    132                 int ax,ay,az,bx,by,bz;
    133                 scanf("%d%d%d%d%d%d",&ax,&ay,&az,&bx,&by,&bz);
    134                 if(ax>bx)
    135                     std::swap(ax,bx);
    136                 if(ay>by)
    137                     std::swap(ay,by);
    138                 if(az>bz)
    139                     std::swap(az,bz);
    140                 ax--,ay--,az--;
    141                 d[++cnt]=(data){i,ax,ay,az,0,-1,0};
    142                 d[++cnt]=(data){i,ax,ay,bz,0,1,0};
    143                 d[++cnt]=(data){i,ax,by,az,0,1,0};
    144                 d[++cnt]=(data){i,bx,ay,az,0,1,0};
    145                 d[++cnt]=(data){i,ax,by,bz,0,-1,0};
    146                 d[++cnt]=(data){i,bx,ay,bz,0,-1,0};
    147                 d[++cnt]=(data){i,bx,by,az,0,-1,0};
    148                 d[++cnt]=(data){i,bx,by,bz,0,1,0};
    149             }
    150         }
    151         
    152         Get();
    153         CDQ(1,cnt);
    154         for(int i=1;i<=n;i++)
    155             if(sek[i]==2)
    156                 printf("%d
    ",ans[i]);
    157     }
    158     return 0;
    159 }
  • 相关阅读:
    小白学phoneGap《构建跨平台APP:phoneGap移动应用实战》连载一(PhoneGap中的API)
    有一种蓝,是神往,是心醉,是心伤
    persits.jpeg 水印组件
    SD卡操作相关的工具SDCardUtils
    apollo 消息分发源代码分析
    tcp ip协议笔记(1)——简单介绍
    百度地图SDK调试SDKInitializer.initialize(getApplicationContext())错误
    一气呵成编完代码的感觉对不正确
    多线程编程1-NSThread
    VIP的转移
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10115791.html
Copyright © 2011-2022 走看看