• bzoj 3262 陌上花开 【CDQ分治】


    三维偏序

    首先把所有花按 x一序,y二序,z三序 排序,然后去重,con记录同样的花的个数,然后进行cdq

    现在假设有[l.r]区间,其中[l,mid] [mid+1,r],已经递归处理完毕。我们把区间[l,mid] [mid+1,r]按 y一序,z二序,x三序 排序,那么现在所有[l,mid]区间里的x比所有[mid+1,r]区间里的x要小,并且在 [l,mid] [mid+1,r]中y是递增的。那么现在考虑[l,mid]中对[mid+1,r]中有贡献的个数,即只需要维护z的大小关系即可。对此用权值树状数组维护。

    p.s. 在处理完区间之后对树状数组的清零操作不要用memset,直接update负值。这样能保证复杂度

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=100005,K=200005;
     6 int n,k,tot,t[K],ans[N];
     7 struct qwe
     8 {
     9     int x,y,z,con,ans;
    10 }a[N];
    11 bool cmp1(const qwe &a,const qwe &b)
    12 {
    13     return (a.x==b.x&&a.y==b.y&&a.z<b.z)||(a.x==b.x&&a.y<b.y)||(a.x<b.x);
    14 }
    15 bool cmp2(const qwe &a,const qwe &b)
    16 {
    17     return (a.y==b.y&&a.z==b.z&&a.x<b.x)||(a.y==b.y&&a.z<b.z)||(a.y<b.y);
    18 }
    19 int read()
    20 {
    21     int r=0,f=1;
    22     char p=getchar();
    23     while(p>'9'||p<'0')
    24     {
    25         if(p=='-')
    26             f=-1;
    27         p=getchar();
    28     }
    29     while(p>='0'&&p<='9')
    30     {
    31         r=r*10+p-48;
    32         p=getchar();
    33     }
    34     return r*f;
    35 }
    36 int lb(int x)
    37 {
    38     return x&(-x);
    39 }
    40 void update(int x,int v)
    41 {
    42     for(int i=x;i<=k;i+=lb(i))
    43         t[i]+=v;
    44 }
    45 int ques(int x)
    46 {
    47     int r=0;
    48     for(int i=x;i>=1;i-=lb(i))
    49         r+=t[i];
    50     return r;
    51 }
    52 void cdq(int l,int r)
    53 {
    54     if(l==r)
    55     {
    56         a[l].ans+=a[l].con-1;
    57         return;
    58     }
    59     int mid=(l+r)>>1;
    60     cdq(l,mid);
    61     cdq(mid+1,r);
    62     sort(a+l,a+1+mid,cmp2);
    63     sort(a+mid+1,a+1+r,cmp2);
    64     int j=l;
    65     for(int i=mid+1;i<=r;i++)
    66     {
    67         for(;j<=mid&&a[j].y<=a[i].y;j++)
    68             update(a[j].z,a[j].con);
    69         a[i].ans+=ques(a[i].z);
    70     }
    71     for(int i=l;i<j;i++)
    72         update(a[i].z,-a[i].con);
    73 }
    74 int main()
    75 {
    76     n=read(),k=read();
    77     for(int i=1;i<=n;i++)
    78         a[i].x=read(),a[i].y=read(),a[i].z=read(),a[i].ans=1;
    79     sort(a+1,a+1+n,cmp1);
    80     for(int i=1;i<=n;i++)
    81         if(i!=1&&a[i].x==a[i-1].x&&a[i].y==a[i-1].y&&a[i].z==a[i-1].z)
    82             a[tot].con++;
    83         else
    84             a[++tot]=a[i],a[tot].con++;
    85     cdq(1,tot);
    86     for(int i=1;i<=tot;i++)
    87         ans[a[i].ans]+=a[i].con;//cout<<n<<endl;
    88     for(int i=1;i<=n;i++)
    89         printf("%d
    ",ans[i]);
    90     return 0;
    91 }

      

  • 相关阅读:
    POJ 3211 Washing Clothes
    MySQL 优化Limit分页
    signed 与 unsigned 有符号和无符号数
    C/C++ 变量的初始化
    C/C++ 变量的初始化
    返回值的判断
    返回值的判断
    《涅槃经》的研读
    《涅槃经》的研读
    Opencv Surf算子特征提取与最优匹配
  • 原文地址:https://www.cnblogs.com/lokiii/p/8108066.html
Copyright © 2020-2023  润新知