求调线段树维护CDQ(qwq
查看原帖
求调线段树维护CDQ(qwq
90971
智子·起源楼主2022/3/19 14:38

rt

#include<bits/stdc++.h>
#define lson node*2
#define rson node*2+1
using namespace std;
const int MAXN=100000+5;
const int MAXK=200000+5;
int n_,n,k,ans[MAXN];
struct data{
	int a,b,c;
	int cnt;
	int cf;
}a[MAXN],b[MAXN];
bool cmp(data a,data b){
	if(a.a!=b.a)return a.a<b.a;
	if(a.b!=b.b)return a.b<b.b;
	return a.c<b.c;
}

int tr[MAXK];
void maintain(int node){
	tr[node]=tr[lson]+tr[rson];
}
void Add(int node,int l,int r,int x,int val){
	if(l==r){
		tr[node]+=val;
		return;
	}
	int mid=(l+r)/2;
	if(x<=mid)Add(lson,l,mid,x,val);
	else Add(rson,mid+1,r,x,val);
	maintain(node);
}
int Query(int node,int l,int r,int L,int R){
	if(L>r||R<l)return 0;
	if(L>=l&&R<=r)return tr[node];
	int mid=(l+r)/2;
	return Query(lson,l,mid,L,R)+Query(rson,mid+1,r,L,R);
}

bool cmp2(data a,data b){
	if(a.b!=b.b)return a.b<b.b;
	return a.c<b.c;
}
void CDQ(int l,int r){
	if(l==r)return;
	int mid=(l+r)/2;
	CDQ(l,mid);
	CDQ(mid+1,r);
	int n1=mid-l+1;
	int n2=r-mid;
	sort(a+l,a+l+n1,cmp2);
	sort(a+mid+1,a+1+mid+n2,cmp2);
	vector<int>tmp;
	for(int i=l,j=mid+1;j<=r;++j){
		while(i<=mid&&a[i].b<=a[j].b){
			tmp.push_back(i);
			Add(1,1,k,a[i].c,1);
			++i;
		}
		a[j].cnt+=Query(1,1,k,1,a[j].c);
	}
	
	int tn=tmp.size();
	for(int i=0;i<tn;++i){
		Add(1,1,k,a[tmp[i]].c,-1);
	}
}
int main(){
	scanf("%d%d",&n_,&k);
	for(int i=1;i<=n_;++i){
		scanf("%d%d%d",&b[i].a,&b[i].b,&b[i].c);
	}
	sort(b+1,b+1+n_,cmp);
	int tmp=0;
	for(int i=1;i<=n_;++i){
		++tmp;
		if(b[i].a!=b[i+1].a||b[i].b!=b[i+1].b||b[i].c!=b[i+1].c){
			a[++n]=b[i];
			a[n].cf=tmp;
			tmp=0;
		}
	}
	CDQ(1,n);
	for(int i=1;i<=n;++i){
		++ans[a[i].cnt+a[i].cf-1];
	}
	for(int i=0;i<n_;++i){
		printf("%d\n",ans[i]);
	}
	return 0;
}
2022/3/19 14:38
加载中...