样例WA
查看原帖
样例WA
787229
kdx_dy楼主2023/3/16 19:56
#include<cstdio>
#include<algorithm>
#define maxn 200005
using namespace std;

struct node
{
	int a,b,c,cnt,ans;
}s1[maxn],s2[maxn];
int n,m,k,mx,top,su[maxn];
int c[maxn];//树状数组

bool cmp1(node x,node y)
{
	if(x.a==y.a)
	{
		if(x.b==y.b)return x.c<y.c;
		else return x.b<y.b;
	}
	else return x.a<y.a;
}//第一维排序

bool cmp2(node x,node y)
{
	if(x.b==y.b)
	return x.c<y.c;
	else return x.b<y.b;
}//第二维排序

int lowbit(int x)
{
	return x&(-x);
}

void add(int x,int y)
{
	while(x<=mx)
	{
		c[x]+=y;
		x+=lowbit(x);
	}
}//树状数组单点加

int query(int x)
{
	int sum=0;
	while(x)
	{
		sum+=c[x];
		x-=lowbit(x);
	}
	return sum;
}//求单点前缀和
//树状数组看得懂吧QAQ

void cdq(int l,int r)
{
	if(l==r)return;
	int mid=(l+r)>>1;
	cdq(l,mid);
	cdq(mid+1,r);//类似于归并排序
	sort(s2+l,s2+mid+1,cmp2);
	sort(s2+mid+1,s2+r+1,cmp2);//第二维为关键字排序
	int i,j=l;
	for(i=mid+1;i<=r;++i)
	{
		while(s2[i].b>=s2[j].b&&j<=mid)
		{
			add(s2[j].c,s2[j].cnt);//在s2[j]位置加上s2[j]的个数
			j++;
		}
		s2[i].ans+=query(s2[i].c);//保证树状数组里的数一定符合条件
	}//类似归并
	for(i=l;i<j;++i)
	add(s2[i].c,-s2[i].cnt);//清空树状数组
}//cdq分治

int main()
{
	scanf("%d%d",&n,&k);
	mx=k;//树状数组的区间
	for(int i=1;i<=n;++i)
	{
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		s1[i].a=a;
		s1[i].b=b;
		s1[i].c=c;
	}//初始化输入
	sort(s1+1,s1+1+n,cmp1);//第一维为关键字排序
	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)
		{
			m++;
			s2[m].a=s1[i].a;
			s2[m].b=s1[i].b;
			s2[m].c=s1[i].c;
			s2[m].cnt=top;
			top=0;
		}
	}//第一维已有序,合并相同节点
	cdq(1,m);//cdq分治
	for(int i=1;i<=m;++i)
	su[s2[i].ans+s2[i].cnt-1]+=s2[i].cnt;
	for(int i=0;i<n;++i)
	printf("%d\n",su[i]);
	return 0;
}

上面是题解的AC代码
下面是我的代码

#include <bits/stdc++.h>
using namespace std;
const int N=200005;
int n,k,top,ans[N],tr[N],sum[N];
struct node{
	int a,b,c,cnt,ans;
	bool operator ==(const node &A)const{
		return a==A.a&&b==A.b&&c==A.c;
	}
}numx[N],num[N];
void Add(int a,int b){
	if(a==0) return;
	while(a<=k) tr[a]+=b,a+=a&(-a);
	return;
}
int Query(int a){
	int ret=0;
	while(a) ret+=tr[a],a-=a&(-a);
	return ret;
}
bool cmp1(node A,node B){
	if(A.a!=B.a) return A.a<B.b;
	if(A.b!=B.b) return A.b<B.b;
	return A.c<B.c;
}
bool cmp2(node A,node B){
	if(A.b!=B.b) return A.b<B.b;
	return A.c<B.c;
}
void solve(int L,int R){
	if(L==R) return;
	int mid=(L+R)>>1;
	solve(L,mid);
	solve(mid+1,R);
	sort(num+L,num+mid+1,cmp2);
	sort(num+mid+1,num+R+1,cmp2);
	int pos=L;
	for(int i=mid+1;i<=R;i++){
		while(num[pos].b<=num[i].b&&pos<=mid) Add(num[pos].c,num[pos].cnt),pos++;
		num[i].ans+=Query(num[i].c);
	}
	for(int i=L;i<pos;i++) Add(num[i].c,-num[i].cnt);
	return;
}
int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++) scanf("%d%d%d",&numx[i].a,&numx[i].b,&numx[i].c);
	sort(numx+1,numx+n+1,cmp1);
	for(int i=1;i<=n;i++){
		if(numx[i]==num[top]) num[top].cnt++;
		else num[++top]=numx[i],num[top].cnt++;
	}
	solve(1,top);
	for(int i=1;i<=top;i++) sum[num[i].ans+num[i].cnt-1]+=num[i].cnt;
	for(int i=0;i<n;i++) printf("%d\n",sum[i]);
	return 0;
}
/*
10 3

1 1 2
1 2 1
1 2 2
1 3 1
1 3 2

2 3 1
2 3 3
3 1 1
3 1 2
3 3 3
*/

哪里出了问题QWQ
(我的num相当于题解的s2)

2023/3/16 19:56
加载中...