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


    Link

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

    Solve

    CDQ分治的模板题,第一维直接排序,第二位用递归,第三位用树状数组

    实在不懂的小伙伴戳这里浅谈CDQ分治

    Code

    #include<bits/stdc++.h>
    using namespace std;
    int N,ans[1000005],K,c[200005],m;
    struct AS{
    	int a,b,c,cnt,ans;
    }a[100005],b[100005];
    inline int read(){
    	int ret=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
    	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
    	return ret*f;
    }
    bool cmp1(AS A,AS B){return (A.a<B.a)||(A.a==B.a&&A.b<B.b)||(A.a==B.a&&A.b==B.b&&A.c<B.c);}
    bool cmp2(AS A,AS B){return (A.b<B.b)||(A.b==B.b&&A.c<B.c);}
    void add_x(int x,int data){
    	for(int i=x;i<=K;i+=i&-i)c[i]+=data;
    	return ;
    }
    int get(int x){
    	int S=0;
    	for(int i=x;i;i-=i&-i)S+=c[i];
    	return S;
    }
    void CDQ(int l,int r){
    	if(l==r)return ;
    	int mid=(r-l>>1)+l;
    	CDQ(l,mid);CDQ(mid+1,r);
    	sort(b+l,b+mid+1,cmp2);
    	sort(b+mid+1,b+r+1,cmp2);
    	int i,j=l;
    	for(i=mid+1;i<=r;i++){
    		while(b[i].b>=b[j].b&&j<=mid){
    			add_x(b[j].c,b[j].cnt);
    			j++;
    		}
    		b[i].ans+=get(b[i].c);
    	}
    	for(int i=l;i<j;i++)add_x(b[i].c,-b[i].cnt);
    }
    int main(){
    	freopen("CDQ.in","r",stdin);
    	freopen("CDQ.out","w",stdout);
    	N=read();K=read();
    	for(int i=1;i<=N;i++)a[i].a=read(),a[i].b=read(),a[i].c=read();
    	sort(a+1,a+1+N,cmp1);
    	for(int i=1;i<=N;i++){
    		if(a[i].a==a[i-1].a&&a[i].b==a[i-1].b&&a[i].c==a[i-1].c){b[m].cnt++;continue;}
    		m++;b[m].a=a[i].a;b[m].b=a[i].b;b[m].c=a[i].c;b[m].cnt++;
    	}
    	CDQ(1,m);
    	for(int i=1;i<=m;i++)ans[b[i].ans+b[i].cnt-1]+=b[i].cnt;
    	for(int i=0;i<N;i++)printf("%d
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    第一次结对作业
    第二次个人编程作业
    第一次个人编程作业
    第一次个人作业
    个人总结-人生如戏
    第二次结对编程
    第一次结对作业
    第二次个人编程作业:代码互改
    第一次个人编程作业
    软件工与UML程第一次作业
  • 原文地址:https://www.cnblogs.com/martian148/p/13857970.html
Copyright © 2020-2023  润新知