#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)