• [Luogu 3810]三维偏序


    Description

    有 $ n $ 个元素,第 $ i $ 个元素有 $ a_i $ 、$ b_i $ 、$ c_i $ 三个属性,设 $ f(i) $ 表示满足 $ a_j leq a_i $ 且 $ b_j leq b_i $ 且 $ c_j leq c_i $ 的 $ j $ 的数量。

    对于 $ d in [0, n) $ ,求 $ f(i) = d $ 的数量

    Input

    第一行两个整数 $ n $ 、$ k $ ,分别表示元素数量和最大属性值。

    之后 $ n $ 行,每行三个整数 $ a_i $ 、$ b_i $ 、$ c_i $ ,分别表示三个属性值。

    Output

    输出 $ n $ 行,第 $ d + 1 $ 行表示 $ f(i) = d $ 的 $ i $ 的数量。

    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 leq n leq 100000, 1 leq k leq 200000 $

    题解

     $CDQ$ 分治模板题。

    三维:

    第一维 $sort$ 排序

    第二维 $CDQ$

    第三维 $bittree$

    我们将第一维排序后,我们用递归实现 $CDQ$ ,取 $mid$ ,算出 $mid$ 左边对 $mid$ 右边的贡献。

    用 $bittree$ 来维护最后一维的大小关系。

     1 #include<set>
     2 #include<map>
     3 #include<cmath>
     4 #include<ctime>
     5 #include<queue>
     6 #include<stack>
     7 #include<cstdio>
     8 #include<string>
     9 #include<vector>
    10 #include<cstdlib>
    11 #include<cstring>
    12 #include<iostream>
    13 #include<algorithm>
    14 #define lowbit(x) ((x)&-(x))
    15 using namespace std;
    16 const int N=100000;
    17 const int K=200000;
    18 
    19 struct point
    20 {
    21     int a,b,c,cnt,ans;
    22 }g[N+5];
    23 int n,m,ans[N+5],c[K+5],num;
    24 bool cmp2(point x,point y) {return x.b==y.b ? x.c<y.c:x.b<y.b;}
    25 bool cmp1(point x,point y) {return x.a==y.a ? cmp2(x,y):x.a<y.a;}
    26 void Add(int x,int y) {for (;x<=m;x+=lowbit(x)) c[x]+=y;}
    27 int Count(int x)
    28 {
    29     int r=0;
    30     for (;x;x-=lowbit(x)) r+=c[x];
    31     return r;
    32 }
    33 void CDQ(int l,int r)
    34 {
    35     if(l==r) return;
    36     int mid=(l+r)>>1;
    37     CDQ(l,mid);
    38     CDQ(mid+1,r);
    39     sort(g+l,g+mid+1,cmp2);
    40     sort(g+mid+1,g+r+1,cmp2);
    41     int t1=l,t2=mid+1;
    42     while(t2<=r)
    43     {
    44         while(t1<=mid&&g[t1].b<=g[t2].b)
    45         {
    46             Add(g[t1].c,g[t1].cnt);
    47             t1++;
    48         }
    49         g[t2].ans+=Count(g[t2].c);
    50         t2++;
    51     }
    52     for (int i=l;i<=t1-1;i++) Add(g[i].c,-g[i].cnt);
    53 }
    54 int main()
    55 {
    56     scanf("%d%d",&n,&m);
    57     for (int i=1;i<=n;i++) scanf("%d%d%d",&g[i].a,&g[i].b,&g[i].c),g[i].cnt=1;
    58     sort(g+1,g+n+1,cmp1);
    59     for (int i=1;i<=n;i++)
    60     {
    61         int k=i+1;
    62         while(g[i].a==g[k].a&&g[i].b==g[k].b&&g[i].c==g[k].c) k++;
    63         num++;
    64         k--;
    65         g[i].cnt+=k-i;
    66         g[num]=g[i];
    67         i=k;
    68     }
    69     CDQ(1,num);
    70     for (int i=1;i<=num;i++) ans[g[i].ans+g[i].cnt-1]+=g[i].cnt;
    71     for (int i=0;i<n;i++) printf("%d
    ",ans[i]);
    72     return 0;
    73 }
  • 相关阅读:
    集合框架(三)
    集合框架(二)
    集合框架(一)
    第九章 持有你的对象
    UML类图
    用a标签设置锚点
    设计原则
    第八章 接口与内部类
    装配Bean
    第33条:用EnumMap代替序数索引
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7406382.html
Copyright © 2020-2023  润新知