CDQ分治求不知道多少维偏序 (持续更新 ]

求三维偏序的模板 :

 1 //Author : 15owzLy1
 2 //luogu3810.cpp
 3 //2018 12 25      16:31:58
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <algorithm>
 7 static char buf[1000001],*p1=buf,*p2=buf;
 8 inline char get_char() {
 9     return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
10 }
11 inline int in() {
12     int x=0;char c=get_char();
13     while(c<'0'||c>'9')c=get_char();
14     while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48), c=get_char();
15     return x;
16 }
17 template<typename T>
18 inline void out(T &x) {
19     int cnt=0;
20     static char s[20];
21     do s[cnt++]=x%10+48; while(x/=10);
22     while(cnt--) putchar(s[cnt]);
23     putchar('\n');
24 }
25 
26 const int N = (int)1e5+5;
27 struct Triple {
28     int x, y, z, val, ans;
29 }a[N], tmp[N];
30 int n, k, ans[N];
31 
32 inline bool cmp(const Triple &x, const Triple &y) {
33     if(x.x==y.x) return x.z==y.z?x.y<y.y:x.z<y.z;
34     return x.x<y.x;
35 }
36 
37 struct BinaryIndexedTree {
38     int t[N<<1];
39     inline void insert(int p, int del) {for(;p<=k;p+=p&-p)t[p]+=del;}
40     inline int ask(int p) {int ret=0;for(;p;p-=p&-p)ret+=t[p];return ret;}
41 }bit;
42 
43 void cdq(int l, int r) {
44     if(l==r) return ;
45     int mid=(l+r)>>1;
46     cdq(l, mid); cdq(mid+1, r);
47     int i=l, j=mid+1, k=l;
48     while(i<=mid&&j<=r)
49         if(a[i].z<=a[j].z)
50             bit.insert(a[i].y, a[i].val), tmp[k++]=a[i++];
51         else
52             a[j].ans+=bit.ask(a[j].y), tmp[k++]=a[j++];
53     for(int p=j;p<=r;p++) a[p].ans+=bit.ask(a[p].y);
54     for(int p=l;p<i;p++)  bit.insert(a[p].y, -a[p].val);
55     if(i<=mid) std::copy(a+i, a+mid+1, tmp+k);
56     if(j<=r)   std::copy(a+j, a+r+1, tmp+k);
57     std::copy(tmp+l, tmp+r+1, a+l);
58 }
59 
60 int main() {
61     int nn=in();
62     k=in();
63     for(int i=1;i<=nn;i++)
64         tmp[i]=(Triple){in(), in(), in(), 0, 0};
65 
66     std::sort(tmp+1, tmp+1+nn, cmp);
67     for(int i=1, cnt=1;i<=nn;i++, cnt++)
68         if(tmp[i].x!=tmp[i+1].x||tmp[i].y!=tmp[i+1].y||tmp[i].z!=tmp[i+1].z)
69             a[++n]=tmp[i], a[n].val=cnt, cnt=0;
70     cdq(1, n);
71     for(int i=1;i<=n;i++) ans[a[i].ans+a[i].val-1]+=a[i].val;
72     for(int i=0;i<nn;i++) out(ans[i]);
73     return 0;
74 }
View Code

 

转载于:https://www.cnblogs.com/15owzLy1-yiylcy/p/10177799.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值