码迷,mamicode.com
首页 > 其他好文 > 详细

【模板】三维偏序

时间:2017-08-21 19:42:19      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:string   image   using   ges   i++   三维   void   分治   技术分享   

技术分享

技术分享

 

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\n",f[i]);
84 }

 

【模板】三维偏序

标签:string   image   using   ges   i++   三维   void   分治   技术分享   

原文地址:http://www.cnblogs.com/Y-E-T-I/p/7406116.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!