BZOJ 3262: 陌上花开 (cdq分治,三维偏序)
程序员文章站
2022-05-14 18:56:45
...
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn=1e5+10;
const int maxk=2e5+10;
int n,k;
struct Triple {
int a,b,c,cnt,ans;
}a[maxn],A[maxn];
bool cmp(const Triple &a,const Triple &b) {
if (a.a!=b.a) {
return a.a<b.a;
}
else if (a.b!=b.b) {
return a.b<b.b;
}
return a.c<b.c;
}
struct BitIndexTree {
int a[maxk];
int lowbit(const int x) {
return x&(-x);
}
void Update(const int x,const int delta) {
for (int i=x;i<=k;i+=lowbit(i)) {
a[i]+=delta;
}
}
void Clean(const int x) {
for (int i=x;i<=k;i+=lowbit(i)) {
if (a[i]) {
a[i]=0;
}
else {
break;
}
}
}
int Query(const int x) {
int ans=0;
for (int i=x;i>0;i-=lowbit(i)) {
ans+=a[i];
}
return ans;
}
}bit;
void CDQ(Triple *l,Triple *r)
{
if (l==r) {
l->ans+=l->cnt-1;
return ;
}
Triple *mid=l+(r-l)/2;
CDQ(l,mid);
CDQ(mid+1,r);
static Triple tmp[maxn];
for (Triple *p=tmp,*p1=l,*p2=mid+1;p<=tmp+(r-l);p++) {
if ((p1<=mid&&p1->b<=p2->b)||p2>r) {
*p=*p1++;
bit.Update(p->c,p->cnt);
}
else {
*p=*p2++;
p->ans+=bit.Query(p->c);
}
}
for (Triple *p=tmp,*q=l;q<=r;p++,q++) {
bit.Clean(p->c);
*q=*p;
}
}
template <typename T>
inline void read(T &x)
{
int f=1;
x=0;
register char ch;
ch=getchar();
while (ch>'9'||ch<'0') {
if (ch=='-') {
f=-f;
}
ch=getchar();
}
while (ch>='0'&&ch<='9') {
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
inline void write(int x)
{
if (x<0) {
putchar('-');
}
if (x>9) {
write(x/10);
}
putchar(x%10+'0');
}
int main()
{
scanf("%d%d",&n,&k);
for (int i=0;i<n;i++) {
read(a[i].a),read(a[i].b),read(a[i].c);
// scanf("%d%d%d",&a[i].a,&a[i].b,&a[i].c);
a[i].cnt=1;
}
sort(a,a+n,cmp);
int cnt=0;
for (int i=0;i<n;i++) {
if (i==0||!(a[i].a==a[i-1].a&&a[i].b==a[i-1].b&&a[i].c==a[i-1].c)) {
A[cnt++]=a[i];
}
else {
A[cnt-1].cnt+=1;
}
}
CDQ(A,A+cnt-1);
static int ans[maxn];
for (int i=0;i<cnt;i++) {
ans[A[i].ans]+=A[i].cnt;
}
for (int i=0;i<n;i++) {
write(ans[i]);
putchar('\n');
// printf("%d\n",ans[i]);
}
return 0;
}