算法模板题系列(1):CDQ分治

主要是自己发现存本地的板子有的时候一下子找不到,写博客备份算了。纯自用 没有讲解。

P3810 【模板】三维偏序(陌上花开)

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define lowbit(x) (x&(-x))
#define ull unsigned long long 
#define pii pair<int,int>
#define ll long long
using namespace std;
const string yes="Yes\n",no="No\n";
const int N = 100005,inf = 1e18,mod=1000000007,M=1e9;
int n,k;
struct fenwick_tree{
    vector<int> tr;
    int k;
    fenwick_tree() {}
    fenwick_tree(int x): tr(x+10){k=x;}
    void add(int x,int y){for(;x<=k;x+=lowbit(x)) tr[x]+=y;}
    int ask(int x,int res=0){for(;x;x-=lowbit(x))res+=tr[x];return res;}
}ft;
struct node{
    int x,y,z,ans,w;
    bool operator <(const node &t) const {return x<t.x||x==t.x&&y<t.y||x==t.x&&y==t.y&&z<t.z;}
    bool operator != (const node &t) const {return x!=t.x||y!=t.y||z!=t.z;}
}a[N],b[N];
int ans[N],cnt;
bool cmp(node x,node y){return x.y==y.y?x.z<y.z:x.y<y.y;}
void cdqsolve(int l,int r){
    if(l==r)return ;
    int mid=(l+r)/2,lp=l,rp=mid+1;
    cdqsolve(l,mid);cdqsolve(mid+1,r);
    sort(a+lp,a+rp,cmp);sort(a+rp,a+r+1,cmp);
    for(;lp<=mid+1||rp<=r+1;){
        if(rp==r+1){for(int i=l;i<lp;i++){ft.add(a[i].z,-a[i].w);}break;}
        else if(lp>mid||a[lp].y>a[rp].y){a[rp].ans+=ft.ask(a[rp].z);rp++;}
        else{ft.add(a[lp].z,a[lp].w);lp++;}
    }
}
void solve(){
    cin>>n>>k;int _n=n;
    for(int i=1;i<=n;i++){cin>>b[i].x>>b[i].y>>b[i].z;}
    sort(b+1,b+1+n);
    for(int i=1,now=1;i<=n;i++,now++){if(b[i]!=b[i+1]){a[++cnt]=b[i];a[cnt].w=now;now=0;}}
    n=cnt;ft=fenwick_tree(k);cdqsolve(1,n);
    for(int i=1;i<=n;i++){ans[a[i].ans+a[i].w-1]+=a[i].w;}
    for(int i=0;i<_n;i++){cout<<ans[i]<<endl;}
}
signed main(){
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cout<<fixed<<setprecision(12);
    int t=1;
    //cin>>t;
    while (t--)
		solve();
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值