BZOJ3262
来自蒟蒻XXJ的做题记录
三维偏序
一维排序 二维cdq 三维树状数组
#include<bits/stdc++.h>
using namespace std;
const int MAXK=200010;
const int MAXN=100010;
inline int in(){
int a(0);char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') a=(a<<1)+(a<<3)+c-'0',c=getchar();
return a;
}
int n,k;
struct Flo{
int a,b,c,s,ans;
bool operator < (const Flo B) const{
if(b==B.b) return c<B.c;
return b<B.b;
}
}a[MAXN],p[MAXN];
int tot,answer[MAXN];
bool cmp(Flo x,Flo y){
if(x.a==y.a&&x.b==y.b) return x.c<y.c;
if(x.a==y.a) return x.b<y.b;
return x.a<y.a;
}
int tree[MAXK];
void change(int pos,int quan){
for(int i=pos;i<=k;i+=(i&-i)) tree[i]+=quan;
}
int query(int pos){
int res(0);
for(int i=pos;i;i-=(i&-i)) res+=tree[i];
return res;
}
void solve(int l,int r){
if(l==r) return;
int mid=(l+r)>>1;
solve(l,mid);
solve(mid+1,r);
sort(p+l,p+mid+1);
sort(p+mid+1,p+r+1);
int i=l,j=mid+1;
while(j<=r){
while(i<=mid&&p[i].b<=p[j].b){
change(p[i].c,p[i].s);
++i;
}
p[j].ans+=query(p[j].c);
j++;
}
for(int ii=l;ii<i;ii++) change(p[ii].c,-p[ii].s);
}
void input(){
n=in();k=in();
for(int i=1;i<=n;i++){
a[i].a=in();a[i].b=in();a[i].c=in();
}
sort(a+1,a+n+1,cmp);
int cnt(0);
for(int i=1;i<=n;i++){
++cnt;
if(a[i].a!=a[i+1].a||a[i].b!=a[i+1].b||a[i].c!=a[i+1].c){
p[++tot]=a[i];p[tot].s=cnt;p[tot].ans=0;
cnt=0;
}
}
}
void xxj(){
solve(1,tot);
for(int i=1;i<=tot;i++) answer[p[i].ans+p[i].s-1]+=p[i].s;
}
void output(){
for(int i=0;i<n;i++) cout<<answer[i]<<endl;
}
int main(){
input();
xxj();
output();
return 0;
}