• 陌上花开


    P2433 - 【BZOJ 3262三维偏序】陌上花开

    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分治:
    算法流程:
    先从中间二分,把左边和右边分别按第二维排序,
    这时第二维是有序的了,第一维并不是有序的,但左区间的都会比右区间的小,
    这时就可以搞两个指针分别指向这两个区间,并且第三维用树状数组维护,
    这样乱搞一下可以维护三维偏序。
     1 #include<set>
     2 #include<map>
     3 #include<queue>
     4 #include<stack>
     5 #include<ctime>
     6 #include<cmath>
     7 #include<string>
     8 #include<vector>
     9 #include<cstdio>
    10 #include<cstdlib>
    11 #include<cstring>
    12 #include<iostream>
    13 #include<algorithm>
    14 #define maxn 200010
    15 using namespace std;
    16 struct data{
    17   int a,b,c,lev,num;
    18 }f[maxn];
    19 int co[maxn],tree[maxn],LOL=0,ans[maxn];
    20 int lowbit(int x){return x&(-x);} 
    21 bool cmp1(const data &a,const data &b){
    22   if(a.a!=b.a) return a.a<b.a;
    23   else{
    24     if(a.b!=b.b) return a.b<b.b;
    25     else return a.c<b.c;
    26   }
    27 }
    28 bool cmp2(const data &a,const data &b){
    29   if(a.b!=b.b) return a.b<b.b;
    30   else return a.c<b.c;
    31 }
    32 void add(int p,int v){
    33   for(int i=p;i<maxn;i+=lowbit(i)){
    34     if(co[i]!=LOL) tree[i]=0;
    35     co[i]=LOL;
    36     tree[i]+=v;
    37   }
    38 }
    39 int find(int p){
    40   int ret=0;
    41   for(int i=p;i;i-=lowbit(i))
    42     if(co[i]==LOL)
    43       ret+=tree[i];
    44   return ret;
    45 }
    46 void QAQ(int l,int r){
    47   if(l==r) return;
    48   int mid=(l+r)>>1;
    49   QAQ(l,mid),QAQ(mid+1,r);
    50   sort(f+l,f+mid+1,cmp2);
    51   sort(f+mid+1,f+r+1,cmp2);
    52   LOL++;
    53   for(int j=mid+1,i=l;j<=r;j++){
    54     for(;f[i].b<=f[j].b&&i<=mid;i++)
    55       add(f[i].c,f[i].num);
    56     f[j].lev+=find(f[j].c);
    57   }
    58 }
    59 int main()
    60 {
    61   freopen("!.in","r",stdin);
    62   freopen("!.out","w",stdout);
    63   int n,m,tot=0;
    64   scanf("%d%d",&n,&m);
    65   for(int i=1;i<=n;i++)
    66     scanf("%d%d%d",&f[i].a,&f[i].b,&f[i].c),f[i].num++;
    67   sort(f+1,f+n+1,cmp1);
    68   for(int i=1;i<=n;i++){
    69     if(i!=1 && f[i-1].a==f[i].a && f[i-1].b==f[i].b && f[i-1].c==f[i].c) f[tot].num++;
    70     else f[++tot].a=f[i].a,f[tot].b=f[i].b,f[tot].c=f[i].c,f[tot].lev=f[i].lev,f[tot].num=f[i].num;
    71   }
    72   QAQ(1,tot);
    73   for(int i=1;i<=tot;i++)
    74     ans[f[i].lev+f[i].num-1]+=f[i].num;
    75   for(int i=0;i<n;i++)
    76     printf("%d
    ",ans[i]);
    77   return 0;
    78 }
    
    
    
     
  • 相关阅读:
    yii2 分页
    yii2 钩子函数
    linux 配置compoer
    Python随心记--迭代器协议和for循环机制
    Python随心记--文件操作处理 open()
    Python随心记--练习
    Python随心记--函数式编程及常用内置函数,及部分实例
    Python随心记--匿名函数
    Python随心记--函数作用域
    Python随心记--局部变量与全局变量
  • 原文地址:https://www.cnblogs.com/pantakill/p/6657798.html
Copyright © 2020-2023  润新知