• bzoj3262 陌上花开 cdq+树状数组


    【bzoj3262】陌上花开

    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

    CDQ分治的裸题,三维偏序。

    先对于一维排序,满足ai递增,然后在分成的两端区间中,左区间以bi排序,右区间以bi排序,处理左

    区间对右区间的影响,因为左区间的ai一定<=右区间ai,然后类似归并操作,如果左bi<=右bi则将

    ci放入树状数组中即可,然后bi查询一下,有多少个。

     1 #include<cstring>
     2 #include<cmath>
     3 #include<cstdio>
     4 #include<iostream>
     5 #include<algorithm>
     6 
     7 #define ll long long
     8 #define NN 2000007
     9 using namespace std;
    10 inline int read()
    11 {
    12     int x=0,f=1;char ch=getchar();
    13     while(ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
    14     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    15     return f*x;
    16 }
    17 
    18 int n,m,tr[NN],ans[NN];
    19 struct Node
    20 {
    21     int a,b,c,s,ans;
    22 }a[NN],p[NN];
    23 
    24 inline int lowbit(int x)
    25 {
    26     return x&(-x);
    27 }
    28 inline void updata(int x,int num)
    29 {
    30     for (int i=x;i<=m;i+=lowbit(i))
    31         tr[i]+=num;
    32 }
    33 inline int query(int x)
    34 {
    35     int res=0;
    36     for (int i=x;i>=1;i-=lowbit(i))
    37         res+=tr[i];
    38     return res;    
    39 }
    40 inline bool cmp1(Node x,Node y)
    41 {
    42     if (x.a==y.a&&x.b==y.b) return x.c<y.c;
    43     if (x.a==y.a) return x.b<y.b;
    44     return x.a<y.a;
    45 }
    46 inline bool cmp2(Node x,Node y)
    47 {
    48     if (x.b==y.b) return x.c<y.c;
    49     return x.b<y.b;
    50 }
    51 void cdq(int l,int r)
    52 {
    53     
    54     if (l==r) return;
    55     int mid=(l+r)>>1;
    56     cdq(l,mid),cdq(mid+1,r);
    57     sort(p+l,p+mid+1,cmp2),sort(p+mid+1,p+r+1,cmp2);
    58     int i=l,j=mid+1;
    59     while(j<=r)
    60     {
    61         while(i<=mid&&p[i].b<=p[j].b)
    62         {
    63             updata(p[i].c,p[i].s);
    64             i++;
    65         }
    66         p[j].ans+=query(p[j].c);
    67         j++;
    68     }
    69     for (int j=l;j<i;j++)//只能到i为止 
    70         updata(p[j].c,-p[j].s);
    71 }
    72 int main()
    73 {
    74     int N=read();m=read();
    75     for (int i=1;i<=N;i++)
    76         a[i].a=read(),a[i].b=read(),a[i].c=read();
    77     sort(a+1,a+N+1,cmp1);
    78     int cnt=0;
    79     for (int i=1;i<=N;i++)
    80     {
    81         cnt++;
    82         if (a[i].a!=a[i+1].a||a[i].b!=a[i+1].b||a[i].c!=a[i+1].c)
    83         {
    84             p[++n]=a[i];
    85             p[n].s=cnt;
    86             cnt=0;
    87         }
    88     }
    89     cdq(1,n);
    90     for (int i=1;i<=n;i++)
    91         ans[p[i].ans+p[i].s-1]+=p[i].s;
    92     for (int i=0;i<N;i++)
    93         printf("%d
    ",ans[i]);    
    94 }
  • 相关阅读:
    Redis涉及的概念
    Redis高级教程
    Redis基础入门
    Java多线程面试题
    Java集合面试题
    Java集合基础
    Java基础面试题总结
    Zookeeper Basics
    GitLab基础入门
    阿里云ECS服务器Docker安装Tomcat过程记录
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7966831.html
Copyright © 2020-2023  润新知