CDQ分治

https://blog.csdn.net/wu_tongtong/article/details/78785836

模板:

三维偏序问题。

hdoj5618 Jam's problem again

传送:http://acm.hdu.edu.cn/showproblem.php?pid=5618

题意:求解有对于每一个三元组$<x_i,y_i,z_i>$,有多少个$<x_j,y_j,z_j>$,满足:$x_i>=x_j && y_i>=y_j && z_i>=z_j$。

数据范围:$1 \le N \le 1e5$,$1 \le x,y,z \le 1e5$

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 struct node{
 5     int x,y,z,id;
 6 }a[maxn],b[maxn];
 7 int tree[maxn],ans[maxn]; 
 8 bool cmp(node p,node q){
 9     return p.x<q.x || p.x==q.x && p.y<q.y || p.x==q.x && p.y==q.y && p.z<q.z; 
10 }
11 int lowbit(int x){
12     return x&-x;
13 }
14 void add(int x,int kk){
15     while (x<maxn){
16         tree[x]+=kk;
17         x+=lowbit(x);
18     }
19 }
20 int query(int x){
21     int res=0;
22     while (x>0){
23         res+=tree[x];
24         x-=lowbit(x);
25     }
26     return res;
27 }
28 void _clear(int x){
29     while (x<maxn){
30         if (tree[x]==0) break;
31         tree[x]=0;
32         x+=lowbit(x);
33     }
34 }
35 void cdq(int l,int r){
36     if (l==r) return ;
37     int mid=(l+r)>>1;
38     cdq(l,mid);
39     cdq(mid+1,r);
40     int i=l,j=mid+1,k=l;
41     while (i<=mid && j<=r){
42         if (a[i].y<=a[j].y){
43             add(a[i].z,1);
44             b[k++]=a[i++];
45         }
46         else{
47             ans[a[j].id]+=query(a[j].z);
48             b[k++]=a[j++];
49         }
50     }
51     while (i<=mid){
52         add(a[i].z,1);
53         b[k++]=a[i++];
54     }
55     while (j<=r){
56         ans[a[j].id]+=query(a[j].z);
57         b[k++]=a[j++];
58     }
59     for (int i=l;i<=r;i++)
60         _clear(a[i].z),a[i]=b[i];
61 }
62 int main(){
63     int t,n; scanf("%d",&t);
64     while(t--){
65         scanf("%d",&n);
66         for (int i=1;i<=n;i++){
67             scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
68             a[i].id=i; ans[i]=0;
69         }
70         sort(a+1,a+1+n,cmp);
71         node tmp={-1,-1,-1,-1};int res=0;
72         for (int i=n;i>=1;i--){
73             if (tmp.x==a[i].x && tmp.y==a[i].y && tmp.z==a[i].z){
74                 ans[a[i].id]+=res;
75                 res++;
76             }
77             else {
78                 tmp=a[i]; res=1;
79             }
80         }
81         cdq(1,n);
82         for (int i=1;i<=n;i++) printf("%d\n",ans[i]);
83     }
84     return 0;
85 }

 

posted @ 2019-07-12 15:01  Changer-qyz  阅读(129)  评论(0编辑  收藏  举报