P3810 【模板】三维偏序(陌上花开)

题面

https://www.luogu.org/problem/P3810

题解

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct node {
  int s1,s2,s3;
  bool operator < (const node rhs) const {
    return s1<rhs.s1 || s1==rhs.s1 && s2<rhs.s2 || s1==rhs.s1 && s2==rhs.s2 && s3<rhs.s3;
  }
} a[100050];

struct newnode {
  int s1,s2,s3;
  int f,v;
  bool operator < (const newnode rhs) const {
    return s2<rhs.s2;
  }
} b[100050];
int n,k,newn;
int ans[100050];

struct fenwick {
  long long tree[200050]={0};
  void insert(int loc,int v) {
    for (int i=loc;i<=k;i+=i&-i) tree[i]+=v;
  }
  int query(int loc) {
    long long sum=0;
    for (int i=loc;i>=1;i-=i&-i) sum+=tree[i];
    return sum;
  }
  void erase(int loc,int v) {
    for (int i=loc;i<=k;i+=i&-i) tree[i]-=v;
  }
} t;

void cdq(int l,int r){
  if (l==r) return;
  int mid=(l+r)/2;
  cdq(l,mid); cdq(mid+1,r);
  sort(b+l,b+mid+1); sort(b+mid+1,b+r+1);
  int i,j;
  j=l;
  for (i=mid+1;i<=r;i++) {
    while (b[j].s2<=b[i].s2 && j<=mid) t.insert(b[j].s3,b[j].v),j++;
    b[i].f+=t.query(b[i].s3);
  }
  for (j--;j>=l;j--) t.erase(b[j].s3,b[j].v);
}

int main(){
  int i;
  scanf("%d %d",&n,&k);
  for (i=1;i<=n;i++) {
    scanf("%d %d %d",&a[i].s1,&a[i].s2,&a[i].s3);
  }
  sort(a+1,a+n+1);
  a[0]=(node){0,0,0};
  int cnt=0;
  for (i=1;i<=n;i++) {
    if (a[i-1].s1==a[i].s1 && a[i-1].s2==a[i].s2 && a[i-1].s3==a[i].s3) 
      b[cnt].v++;
    else {
      cnt++;
      b[cnt]=(newnode){a[i].s1,a[i].s2,a[i].s3,0,1};
    }
  }
  for (i=1;i<=cnt;i++) b[i].f+=b[i].v-1;
  cdq(1,cnt);
  for (i=1;i<=cnt;i++) ans[b[i].f]+=b[i].v;
  for (i=0;i<n;i++) printf("%d\n",ans[i]);
}

 

posted @ 2019-08-28 23:58  HellPix  阅读(151)  评论(0编辑  收藏  举报