• [模板]三维偏序


    description

    洛谷

    data range

    [nle 10^5,mle 2 imes 10^5 ]

    kd-tree solution

    直到现在才开始做三维偏序...还是用的(kd-tree)...

    险险卡过.jpg

    code

    #include<bits/stdc++.h>
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstring>
    #include<complex>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define FILE "a"
    #define Cpy(x,y) (memcpy(x,y,sizeof(x)))
    #define Set(x,y) (memset(x,y,sizeof(x)))
    #define mp make_pair
    #define pb push_back
    #define RG register
    #define il inline
    using namespace std;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef vector<int>VI;
    typedef long long ll;
    typedef double dd;
    const dd eps=1e-10;
    const int mod=1e9+7;
    const int N=200010;
    const int M=205;
    const dd pi=acos(-1);
    const int inf=2147483647;
    const ll INF=1e18+1;
    const ll P=100000;
    il int read(){
    	RG int data=0,w=1;RG char ch=getchar();
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')data=(data<<3)+(data<<1)+(ch^48),ch=getchar();
    	return data*w;
    }
    
    il void file(){
    	srand(time(NULL)+rand());
    	freopen(FILE".in","r",stdin);
    	freopen(FILE".out","w",stdout);
    }
    
    int n,tot,rt,cd,f[N];
    struct node{int d[3];}p[N];
    bool operator <(node a,node b){return a.d[0]<b.d[0];}
    struct kdnode{int d[2],l[2],r[2],s[2],v,sum;}t[N];
    bool operator <(kdnode x,kdnode y){return x.d[cd]<y.d[cd];}
    int l[2],r[2];
    
    #define ls t[i].s[0]
    #define rs t[i].s[1]
    #define mid ((l+r)>>1)
    il void update(int i){
    	for(int k=0;k<2;k++){
    		t[i].l[k]=t[i].r[k]=t[i].d[k];
    		if(ls){
    			t[i].l[k]=min(t[i].l[k],t[ls].l[k]);
    			t[i].r[k]=max(t[i].r[k],t[ls].r[k]);
    		}
    		if(rs){
    			t[i].l[k]=min(t[i].l[k],t[rs].l[k]);
    			t[i].r[k]=max(t[i].r[k],t[rs].r[k]);			
    		}
    	}
    	t[i].sum=t[ls].sum+t[rs].sum+t[i].v;
    }
    
    int rebuild(int l,int r,int D){
    	if(l>r)return 0;
    	cd=D;nth_element(t+l,t+mid,t+r+1);
    	t[mid].s[0]=rebuild(l,mid-1,D^1);
    	t[mid].s[1]=rebuild(mid+1,r,D^1);
    	update(mid);return mid;
    }
    
    void insert(int &i,int D){
    	if(!i){
    		i=++tot;t[i].v=t[i].sum=0;
    		t[i].l[0]=t[i].r[0]=t[i].d[0]=r[0];
    		t[i].l[1]=t[i].r[1]=t[i].d[1]=r[1];
    	}
    	if(r[0]==t[i].d[0]&&r[1]==t[i].d[1])
    	{t[i].v++;t[i].sum++;return;}
    	insert(t[i].s[t[i].d[D]>r[D]],D^1);
    	update(i);
    }
    
    #define ckm(dd) (l[dd]<=t[i].l[dd]&&t[i].r[dd]<=r[dd])
    #define ckd(dd) (l[dd]<=t[i].d[dd]&&t[i].d[dd]<=r[dd])
    #define cke(dd) (t[i].r[dd]<l[dd]||r[dd]<t[i].l[dd])
    int query(int i,int D){
    	if(!i||cke(0)||cke(1))return 0;
    	if(ckm(0)&&ckm(1))return t[i].sum;
    	RG int ret=0;
    	if(ckd(0)&&ckd(1))ret+=t[i].v;
    	ret+=query(ls,D^1)+query(rs,D^1);
    	return ret;
    }
    
    int main()
    {
    	n=read();read();
    	for(RG int i=1;i<=n;i++)a
    		for(RG int j=0;j<3;j++)
    			p[i].d[j]=read();
    	sort(p+1,p+n+1);
    
    	RG int pos=1,nxt=1,lim=10000,ans;
    	while(pos<=n){
    		while(nxt<=n&&(nxt==pos||p[nxt].d[0]==p[nxt-1].d[0])){
    			r[0]=p[nxt].d[1];r[1]=p[nxt].d[2];insert(rt,0);nxt++;
    		}
    		for(RG int i=pos;i<nxt;i++){
    			r[0]=p[i].d[1];r[1]=p[i].d[2];f[ans=query(rt,0)-1]++;
    		}
    		pos=nxt;
    		if(pos<=n&&pos>=lim){
    			rt=rebuild(1,tot,0);
    			lim=pos/10000*10000+10000;
    		}
    	}
    	for(RG int i=0;i<n;i++)printf("%d
    ",f[i]);
    	return 0;
    }
    
    

    CDQ solution

    现在才学(CDQ)..弱

    code

    不过(CDQ)的代码真的很短

    #include<bits/stdc++.h>
    #define RG register
    #define il inline
    using namespace std;
    const int N=200010;
    il int read(){
    	RG int data=0,w=1;RG char ch=getchar();
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
    	return data*w;
    }
    int n,m,k,ans[N],f[N],tr[N];struct node{int a,b,c,w,id;}p[N],tmp[N];
    bool operator <(node x,node y){
    	return x.a<y.a||(x.a==y.a&&(x.b<y.b||(x.b==y.b&&x.c<y.c)));
    }
    bool cmp1(node x,node y){return x.a==y.a&&x.b==y.b&&x.c==y.c;}
    bool cmp2(node x,node y){return x.b<=y.b||(x.b==y.b&&x.c<=y.c);}
    #define low(x) (x&(-x))
    il void insert(int i,int v){for(;i<=k;i+=low(i))tr[i]+=v;}
    il int query(int i){RG int r=0;for(;i;i-=low(i))r+=tr[i];return r;}
    il void clear(int i){for(;i<=k;i+=low(i))tr[i]=0;}
    void cdq(int l,int r){
    	if(l==r)return;RG int mid=(l+r)>>1;cdq(l,mid);cdq(mid+1,r);
    	for(RG int i=l,p1=l,p2=mid+1;i<=r;i++){
    		if((p1<=mid&&cmp2(p[p1],p[p2]))||p2==r+1){
    			insert(p[p1].c,p[p1].w);tmp[i]=p[p1++];
    		}
    		else{ans[p[p2].id]+=query(p[p2].c);tmp[i]=p[p2++];}
    	}
    	for(RG int i=l;i<=r;i++)clear(tmp[i].c),p[i]=tmp[i];
    }
    int main()
    {
    	n=read();k=read();
    	for(RG int i=1;i<=n;i++){p[i].a=read();p[i].b=read();p[i].c=read();}
    	sort(p+1,p+n+1);
    	for(RG int i=1;i<=n;i++){
    		p[++m]=p[i];p[m].w=1;p[m].id=m;
    		while(i<n&&cmp1(p[i],p[i+1])){i++;p[m].w++;}
    		ans[m]=p[m].w-1;
    	}
    	cdq(1,m);
    	for(RG int i=1;i<=m;i++)f[ans[p[i].id]]+=p[i].w;
    	for(RG int i=0;i<n;i++)printf("%d
    ",f[i]);
    	return 0;
    }
    
    
  • 相关阅读:
    vue组件重新加载的方法
    事件触发方法获取当前值的写法 (含方法要传2个参数的写法)
    mac 解压 rar压缩文件
    表格
    小米8安装charles证书方法
    视频结构化技术栈全解析
    多目标跟踪全解析,全网最全
    SpringBoot
    技术方案设计的方法
    Java的强引用、软引用、弱引用、虚引用
  • 原文地址:https://www.cnblogs.com/cjfdf/p/9656163.html
Copyright © 2020-2023  润新知