mxqz三维偏序模板题
查看原帖
mxqz三维偏序模板题
766058
HCAM楼主2022/11/7 20:28
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read() {
	ll f=1,x=0;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) {x=x*10+ch-48;ch=getchar();}
	return x*f;
}
const ll N=200005;
struct V {
	ll a,b,c,app,bh;
}v[N];
bool precmp(V x,V y) {
	if(x.a==y.a) {
		if(x.b==y.b) return x.c>y.c;
		return x.b>y.b;
	}
	return x.a>y.a;
}
bool stb(V x,V y) {
	if(x.b==y.b) return x.c>y.c;
	return x.b>y.b;
}
ll n,k,ans[N],fn[N];
bool equal(int x,int y) {
	return ((v[x].a==v[y].a)&(v[x].b==v[y].b)&(v[x].c==v[y].c));
}
struct SGtree {
	ll nd[4*N],sum;
	void pushup(int t) {
		nd[t]=nd[2*t]+nd[2*t+1];
	}
	void Clear(int t,int l,int r) {
		if(l==r) {
			nd[t]=0;
			return ;
		}
		int mid=(l+r)/2;
		Clear(2*t,l,mid);
		Clear(2*t+1,mid+1,r);
		pushup(t);
	}
	void clear() {
		Clear(1,1,k); 
	}
	void Query(int t,int l,int r,int ll,int rr) {
		if(ll<=l&&r<=rr) {
			sum+=nd[t];
			return ;
		}
		int mid=(l+r)/2;
		if(ll<=mid) Query(2*t,l,mid,ll,rr);
		if(rr>=mid+1) Query(2*t+1,mid+1,r,ll,rr);
	}
	ll query(int l,int r) {
		sum=0;
		Query(1,1,k,l,r);
		return sum;
	}
	void Update(int t,int l,int r,int p,int val) {
		if(l==r) {
			nd[t]+=val;
			return ;
		}
		int mid=(l+r)/2;
		if(p<=mid) Update(2*t,l,mid,p,val);
		if(p>=mid+1) Update(2*t+1,mid+1,r,p,val); 
		pushup(t);
	}
	void update(int p,int val) {
		Update(1,1,k,p,val);
	}
}sgt;
void solve(int l,int r) {
	if(l==r) return ;
	int mid=(l+r)/2;
	solve(l,mid);
	solve(mid+1,r);
//	sgt.clear();
	sort(v+l,v+mid+1,stb);
	sort(v+mid+1,v+r+1,stb);
//	cout<<l<<' '<<r<<'\n';
//	for(int i=1;i<=n;i++) cout<<v[i].a<<' ';
//	cout<<'\n';
//	sgt.clear();
	for(int i=mid+1;i<=r;i++) sgt.update(v[i].c,v[i].app);
	int lp,rp;
	for(lp=l,rp=mid;lp<=mid;lp++) {
		while(rp<r&&v[rp+1].b>v[lp].b) {
			rp++;
			sgt.update(v[rp].c,-v[rp].app);
		}
//		if(v[lp].bh==3) cout<<"AD"<<l<<' '<<r<<' '<<lp<<' '<<sgt.query(1,v[lp].c)<<'\n';
		ans[v[lp].bh]+=sgt.query(1,v[lp].c);
	}
	while(rp<r) {
		rp++;
		sgt.update(v[rp].c,-v[rp].app);
	}
	sort(v+l,v+r+1,precmp); //--------------
}
int main() {
//	freopen("input.txt","r",stdin);
//	freopen("output.txt","w",stdout);
	n=read(),k=read();
	for(int i=1;i<=n;i++) {
		v[i].a=read(),v[i].b=read(),v[i].c=read();
		v[i].app=1;
	}
	sort(v+1,v+n+1,precmp);
	ll nw=n;
    for(int i=1;i<=n;i++) {
//    	cout<<i<<' '<<v[i].a<<' '<<v[i].b<<' '<<v[i].c<<'\n';
    	if(equal(i,i+1)) v[i].a=0,nw--,v[i+1].app+=v[i].app;
	}
	sort(v+1,v+n+1,precmp);
    ll tmp=n;
	n=nw;nw=tmp;
    for(int i=1;i<=n;i++) v[i].bh=i;
    solve(1,n);
    for(int i=1;i<=n;i++) {
//    	cout<<v[i].a<<' '<<ans[i]<<' '<<v[i].app<<'\n';
//        if(ans[i]+v[i].app-1==1) {
//        	cout<<i<<' '<<v[i].a<<' '<<v[i].b<<' '<<v[i].c<<'\n';
//		}
    	fn[ans[i]+v[i].app-1]+=v[i].app;
	}
	for(int i=0;i<=nw-1;i++) cout<<fn[i]<<'\n';
	return 0;
}

正常来说solve函数的倒数第二行的sort(v+l,v+r+1,precmp);不加就能通过,但我发现只有加上才能过。有没有大佬能指点一下,谢谢。

2022/11/7 20:28
加载中...