• 【模板】三维偏序


    CDQ分治

    首先按a排序,分成两段后再分别对两段按b排序,这样就保证了w[x2].a>=w[x1].a,消去一维

    按b排序后找到w[x2].b>=w[x1].b的同时满足w[x2].c>=w[x1].c的值

    按b排序后有单调性,所以b可以在O(n)时间,对于c,每找到一个w[x1]满足b的条件,则在树状数组中+1

    w[x2].ans+=query(w[x2].c)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 struct Node
     7 {
     8     int a,b,c,cnt,ans;
     9 }w[100001];
    10 int m,n,c[2000001],ans,f[100001];
    11 bool cmp2(Node a,Node b)
    12 {
    13     if (a.b==b.b)
    14      return a.c<b.c;
    15      else return a.b<b.b;
    16 }
    17 bool cmp1(Node a,Node b)
    18 {
    19     if (a.a==b.a)
    20      return cmp2(a,b);
    21      else return a.a<b.a;
    22 }
    23 void add(int x,int d)
    24 {
    25     while (x<=m)
    26     {
    27      c[x]+=d;
    28      x+=(x&(-x));
    29     }
    30 }
    31 int query(int x)
    32 {int s=0;
    33     while (x)
    34     {
    35      s+=c[x];
    36      x-=(x&(-x));
    37     }
    38   return s;
    39 }
    40 void cdq(int l,int r)
    41 {int r1,r2;
    42     int mid=(l+r)/2;
    43     if (l==r)
    44     return;
    45      cdq(l,mid);cdq(mid+1,r);
    46      sort(w+l,w+mid+1,cmp2);
    47      sort(w+mid+1,w+r+1,cmp2);
    48      r1=l;r2=mid+1;
    49      while (r2<=r)
    50      {
    51         while (r1<=mid&&w[r1].b<=w[r2].b)
    52          add(w[r1].c,w[r1].cnt),r1++;
    53          w[r2].ans+=query(w[r2].c);
    54         r2++;
    55      }
    56     for (int i=l;i<=r1-1;i++)
    57     add(w[i].c,-w[i].cnt);
    58 }
    59 int main()
    60 {int i,j,num=0;
    61     cin>>n>>m;
    62     for (i=1;i<=n;i++)
    63     {
    64       scanf("%d%d%d",&w[i].a,&w[i].b,&w[i].c);
    65       w[i].cnt=1;
    66     }
    67     sort(w+1,w+n+1,cmp1);
    68     for (i=1;i<=n;i++)
    69     {
    70         int k=i+1;
    71         while (w[i].a==w[k].a&&w[i].b==w[k].b&&w[i].c==w[k].c)
    72          k++;
    73          num++;
    74          k--;
    75          w[i].cnt+=k-i;
    76          w[num]=w[i];
    77          i=k;
    78     }
    79     cdq(1,num);
    80     for (i=1;i<=num;i++)
    81     f[w[i].ans+w[i].cnt-1]+=w[i].cnt;
    82     for (i=0;i<n;i++)
    83     printf("%d
    ",f[i]);
    84 }
  • 相关阅读:
    day10
    python学习第六天
    Python学习第五天
    python学习第四天第一部分
    python学习第三天第一部分
    python学习第二天第二部分
    python学习第二天第一部分
    崔西凡JavaWeb笔记day13-day15(2016年8月30日22:36:30)
    崔希凡JavaWeb笔记day10~day12(2016年8月22日11:55:20)
    崔希凡-javaWeb-笔记day07-day09(2016年7月26日23:14:40)
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7406116.html
Copyright © 2020-2023  润新知