陌上开花(CDQ分治)

题解

三维偏序裸题。。。

一般三维偏序是第一维排序,第二维CDQ分治,第三维树状数组。

模板题还是看代码吧。。。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 const int N=200100;
 8 const int M=200100;
 9 int n,d,tr[M],ans[N];
10 struct query{
11     int a,b,c;
12     int w,ans;
13     bool operator <(const query &x)const{
14         if(x.a==a){
15             if(x.b==b)return x.c>c;
16             else return x.b>b;
17         }
18         else return x.a>a;
19     }
20 }q[N],c[N];
21 int lowbit(int x){
22     return x&-x;
23 } 
24 void add(int x,int w){
25     for(int i=x;i<=N-100;i+=lowbit(i)){
26         tr[i]+=w;
27     }
28 }
29 int getsum(int x){
30     int ans=0;
31     for(int i=x;i>=1;i-=lowbit(i)){
32         ans+=tr[i];
33     }
34     return ans;
35 }
36 void cdq(int l,int r){
37     if(l==r)return;
38     int mid=(l+r)>>1;
39     cdq(l,mid);cdq(mid+1,r);
40     int ll=l;
41     int rl=mid+1;
42     int now=0;
43     while(ll<=mid&&rl<=r){
44         if(q[ll].b<=q[rl].b){
45             add(q[ll].c,q[ll].w);
46             c[++now]=q[ll++];
47         }
48         else{
49             q[rl].ans+=getsum(q[rl].c);
50             c[++now]=q[rl++];
51         }
52     }
53     while(ll<=mid){
54         add(q[ll].c,q[ll].w);
55         c[++now]=q[ll++];
56     }
57     while(rl<=r){
58         q[rl].ans+=getsum(q[rl].c);
59         c[++now]=q[rl++];
60     }
61     for(int i=l;i<=mid;i++)add(q[i].c,-q[i].w);
62     for(int i=l;i<=r;i++){
63         q[i]=c[i-l+1];
64     }
65 }
66 int main(){
67     scanf("%d%d",&n,&d);
68     for(int i=1;i<=n;i++){
69         scanf("%d%d%d",&q[i].a,&q[i].b,&q[i].c);
70         q[i].w=1;
71     }
72     sort(q+1,q+1+n);
73 //    for(int i=1;i<=n;i++){
74 //        cout<<q[i].a<<" "<<q[i].b<<" "<<q[i].c<<endl;
75 //    }
76     int pd=1;
77     for(int i=2;i<=n;i++){
78         if(q[pd].a==q[i].a&&q[pd].b==q[i].b&&q[pd].c==q[i].c)q[pd].w++;
79         else q[++pd]=q[i]; 
80     }
81     int num=n;
82     n=pd;
83     cdq(1,pd);
84     for(int i=1;i<=n;i++)ans[q[i].ans+q[i].w]+=q[i].w;
85     for(int i=1;i<=num;i++)printf("%d
",ans[i]);
86     return 0; 
87 }
原文地址:https://www.cnblogs.com/Xu-daxia/p/9460085.html