震惊!!苦练OI两天半萌新不会写CDQ嵌套,求调
查看原帖
震惊!!苦练OI两天半萌新不会写CDQ嵌套,求调
497275
trp_hy楼主2023/7/17 17:54
#include<bits/stdc++.h>
#define N 500005
#define lb(x) ((x)&(-x))
using namespace std;

int n,m;
int an[N],tr[N];
struct node{int a,b,c,cnt,ans,op;}s[N],s1[N];

inline int read(){
	int x=0,w=0; char c=0;
	while(!isdigit(c)){w|=c=='-';c=getchar();}
	while(isdigit(c)){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
	return w?-x:x;
}

inline bool cmp1(node x,node 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;
}

inline bool cmp2(node x,node y){//按第二属性排序 
	if(x.b==y.b) return x.c<y.c;
	return x.b<y.b;
}

inline bool cmp3(node x,node y){//按第三属性排序 
	return x.c<y.c;
}

inline void add(int x,int k){
	for(;x<=m;x+=lb(x)) tr[x]+=k;
}

inline int ask(int x){
	int ans=0;
	for(;x;x-=lb(x)) ans+=tr[x];
	return ans;
}

inline void cdq2(int l,int r){
	if(l==r) return;
	int mid=l+r>>1;
	cdq2(l,mid);
	cdq2(mid+1,r);
	for(int i=l,j=mid+1,sum=0;j<=r||i<=mid;){
		if(i<=mid&&(s1[i].c<=s1[j].c||j>r)) sum+=s1[i++].b;
		else{
			if(!s1[j].op) s1[j].ans+=sum;
			j++;
		}
	} 
	sort(s1+l,s1+r+1,cmp3);
}

inline void cdq1(int l,int r){
	if(l==r) return;
	int mid=l+r>>1;
	cdq1(l,mid);
	cdq1(mid+1,r);
	for(int i=l;i<=mid;++i) s[i].op=1;
	for(int i=mid+1;i<=r;++i) s[i].op=0;
	sort(s+l,s+r+1,cmp2);
	for(int i=l;i<=r;++i) s1[i]=s[i];
	cdq2(l,r);
}

signed main(){
	n=read(),m=read();
	for(int i=1;i<=n;++i){
		s1[i].a=read();
		s1[i].b=read();
		s1[i].c=read();
	}
	sort(s1+1,s1+n+1,cmp1);
	int top=0,mm=0;
	for(int i=1;i<=n;++i){
		top++;
		if(s1[i].a!=s1[i+1].a||s1[i].b!=s1[i+1].b||s1[i].c!=s1[i+1].c){
			mm++;
			s[mm].a=s1[i].a;
			s[mm].b=s1[i].b;
			s[mm].c=s1[i].c;
			s[mm].cnt=top;
			top=0;
		}
	}
	cdq1(1,mm);
	for(int i=1;i<=mm;++i) an[s[i].ans+s[i].cnt-1]+=s[i].cnt;
	for(int i=0;i<n;++i) printf("%d\n",an[i]);
	return 0;
}
2023/7/17 17:54
加载中...