zoukankan      html  css  js  c++  java
  • bzoj3262陌上花开 cdq分治

    3262: 陌上花开

    Time Limit: 20 Sec  Memory Limit: 256 MB
    Submit: 2794  Solved: 1250
    [Submit][Status][Discuss]

    Description

    有n朵花,每朵花有三个属性:花形(s)、颜色(c)、气味(m),又三个整数表示。现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量。定义一朵花A比另一朵花B要美丽,当且仅当Sa>=Sb,Ca>=Cb,Ma>=Mb。显然,两朵花可能有同样的属性。需要统计出评出每个等级的花的数量。

    Input

    第一行为N,K (1 <= N <= 100,000, 1 <= K <= 200,000 ), 分别表示花的数量和最大属性值。
    以下N行,每行三个整数si, ci, mi (1 <= si, ci, mi <= K),表示第i朵花的属性

    Output

    包含N行,分别表示评级为0...N-1的每级花的数量。

    Sample Input

    10 3
    3 3 3
    2 3 3
    2 3 1
    3 1 1
    3 1 2
    1 3 1
    1 1 2
    1 2 2
    1 3 2
    1 2 1

    Sample Output

    3
    1
    3
    0
    1
    0
    1
    0
    0
    1

    HINT

    1 <= N <= 100,000, 1 <= K <= 200,000

    Source

    树套树 CDQ分治

    三维偏序 -最裸的cdq分治
    首先把所有元素按照x排序,然后进行cdq分治

    在分治时,总是由分治左区间向右区间转移答案,可以保证转移的x满足条件
    按照y排序再转移,保证y有序
    树状数组维护z,保证z有序

    由于分治是层层递归下去的,所以每个点一定都会计算完它的前缀贡献的答案

    另外,cdq分治的核心思想是:先处理左区间,再处理左区间对右区间贡献的答案,最后处理右区间
    但对于这个题,可以先左再右,最后左向右贡献答案

     1 #include<bits/stdc++.h>
     2 #define N 100005
     3 using namespace std;
     4 int n,m,pa,pb,acnt,bcnt,tot,cnt[N],pos[N],c[N<<1];
     5 struct info{int x,y,z,id,ans;}q[N],a[N],b[N];
     6 bool cmp1(info a,info b){
     7     if(a.x==b.x){
     8         if(a.y==b.y)return a.z<b.z;
     9         return a.y<b.y;
    10     }
    11     return a.x<b.x;
    12 }
    13 bool cmp2(info a,info b){return a.y<b.y;}
    14 void add(int p,int v){
    15     while(p<=m){
    16         c[p]+=v;
    17         p+=p&-p;
    18     }
    19 }
    20 int query(int p){
    21     int ret=0;
    22     while(p){
    23         ret+=c[p];
    24         p-=p&-p;
    25     }
    26     return ret;
    27 }
    28 void cdq(int l,int r){
    29     if(l>=r)return;
    30     int mid=(l+r)>>1;
    31     cdq(l,mid);
    32     acnt=bcnt=0;
    33     for(int i=l;i<=mid;++i)a[++acnt]=q[i];
    34     for(int i=mid+1;i<=r;++i)b[++bcnt]=q[i];
    35     sort(a+1,a+1+acnt,cmp2);
    36     sort(b+1,b+1+bcnt,cmp2);
    37     pa=pb=1;tot=0;
    38     while(pb<=bcnt){
    39         while(pa<=acnt&&a[pa].y<=b[pb].y){
    40             add(a[pa].z,1);
    41             pos[++tot]=a[pa].z;
    42             ++pa;
    43         }
    44         q[b[pb].id].ans+=query(b[pb].z);
    45         ++pb;
    46     }
    47     for(int i=1;i<=tot;++i)add(pos[i],-1);
    48     cdq(mid+1,r);
    49 }
    50 int main(){
    51     scanf("%d%d",&n,&m);
    52     for(int i=1;i<=n;++i)
    53     scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].z);
    54     sort(q+1,q+1+n,cmp1);
    55     for(int i=1;i<=n;++i)q[i].id=i;
    56     cdq(1,n);
    57     for(int i=n;i;--i)
    58     if(q[i].x==q[i+1].x&&q[i].y==q[i+1].y&&q[i].z==q[i+1].z)
    59     q[i].ans=max(q[i].ans,q[i+1].ans);
    60     for(int i=1;i<=n;++i)++cnt[q[i].ans];
    61     for(int i=0;i<n;++i)printf("%d
    ",cnt[i]);
    62     return 0;
    63 }
  • 相关阅读:
    Mybatis之动态构建SQL语句(转)
    清理docker大日志文件
    删除一直处于deleting状态的数据卷
    kvm虚拟化平台搭建
    交换机的Access口与Trunk口
    linux命令tee用法
    openstack之镜像管理
    Sword redis存取二进制数据
    Sword STL迭代器prev,next相关函数
    C++ 拷贝构造函数之const关键字
  • 原文地址:https://www.cnblogs.com/wsy01/p/8134102.html
Copyright © 2011-2022 走看看