链接:https://www.luogu.org/problemnew/show/P3810
思路:写这题时发现昨天写hdu那个模板题的板子可能是不对的,对于相等的两个点应该先去重再进行程序,因为cdq中排序结束后相等的点出来时不一定是紧挨着的了,所以再用之前的写法是可能出错的,不过hdu那题的数据好像不是很强,加个去重理解也很简单,待会会把hdu那题去重的正确写法改上去的。
AC代码:
#include<bits/stdc++.h>
#define INF 0x3F3F3F3F
#define endl '\n'
#define pb push_back
#define css(n) cout<<setiosflags(ios::fixed)<<setprecision(n);
#define sd(a) scanf("%d",&a)
#define sld(a) scanf("%lld",&a)
#define m(a,b) memset(a,b,sizeof a)
#define p_queue priority_queue
using namespace std;
typedef long long ll;
const int maxn=100005;
const int maxm=200005;
int n,m,k;
int n1;
int t;
double a,b;
struct node
{
int x,y,z;
int id;
int sum;
int num;
}dian[maxn],p1[maxn];
bool comp1(node a,node b)
{
if(a.x!=b.x) return a.x<b.x;
if(a.y!=b.y) return a.y<b.y;
return a.z<b.z;
}
bool comp2(node a,node b)
{
if(a.y!=b.y)
return a.y<b.y;
return a.z<b.z;
}
int tre[maxm];
int N;
int lowbit(int x)
{
return x&(-x);
}
void add(int pos,int val)
{
while(pos<=N)
{
tre[pos]+=val;
pos+=lowbit(pos);
}
}
int ask(int pos)
{
int ans=0;
while(pos)
{
ans+=tre[pos];
pos-=lowbit(pos);
}
return ans;
}
void cdq(int l,int r)
{
if(l==r) return;
int mid=(l+r)>>1;
cdq(l,mid),cdq(mid+1,r);
sort(p1+l,p1+mid+1,comp2);//sort的第二个参数是结束的地址+1
sort(p1+mid+1,p1+r+1,comp2);
int j=l;
for(int i=mid+1;i<=r;i++)
{
for(;j<=mid;j++)
{
if(p1[j].y>p1[i].y) break;
add(p1[j].z,p1[j].num);
}
p1[i].sum+=ask(p1[i].z);
}
for(int zz=l;zz<=j-1;zz++)
{
add(p1[zz].z,-p1[zz].num);
}
/* for(j=j-1;j>=l;j--)
{
add(dian[j].z,-1);
}*/
}
int num[maxm]={0};
int main()
{
sd(n);
sd(k);
N=k;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&dian[i].x,&dian[i].y,&dian[i].z);
dian[i].id=i;
dian[i].sum=0;
}
sort(dian+1,dian+1+n,comp1);
n1=1;
for(int i=1;i<=n;)
{
int j=i;
int c=0;
while(j<=n)
{
if(dian[j].x==dian[i].x&&dian[j].y==dian[i].y&&dian[j].z==dian[i].z)
{
c++;
j++;
}
else break;
}
p1[n1]=dian[i];
p1[n1].num=c;
n1++;
i=j;
}
n1--;
cdq(1,n1);
int i=1;
// int mxx=0;
int j;
/* for(int i=1;i<=n;i++)
{
cout<<dian[i].id<<"---"<<dian[i].x<<",,,"<<dian[i].sum<<endl;
}*/
for(int i=1;i<=n1;i++)
{
num[p1[i].sum+p1[i].num-1]+=p1[i].num;
}
for(int i=0;i<n;i++)
{
printf("%d\n",num[i]);
}
return 0;
}