传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3262
今天原本打算学一下cdq分治的……
就找了几道模板题
然后发现全都可以树套树……
唉……树套树就树套树吧
三维偏序
一维排序
二维树状数组
三维平衡树
Code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n,k,size;
struct tup{
int x,y,z,s;
tup(int _x=0,int _y=0,int _z=0,int _s=0):x(_x),y(_y),z(_z),s(_s){}
bool operator<(tup oth)const{
return x==oth.x?y==oth.y?z<oth.z:y<oth.y:x<oth.x;
}
bool operator==(tup oth)const{return x==oth.x&&y==oth.y&&z==oth.z;}
bool operator!=(tup oth)const{return !(*this==oth);}
}a[maxn],b[maxn];
struct node{
int val,key,sum,s;
node *c[2];
node(int _val=0,int _s=0,node *C=0){
val=_val;key=rand();sum=s=_s;
c[0]=c[1]=C;
}
void rz(){
sum=c[0]->sum+s+c[1]->sum;
}
}pool[maxn],*Null;
node *newnode(int _val=0,int _s=0,node *C=0){
static int tot=0;
if(tot<maxn){
pool[tot].val=_val;
pool[tot].key=rand();
pool[tot].sum=pool[tot].s=_s;
pool[tot].c[0]=pool[tot].c[1]=C;
return &pool[tot++];
}else return new node(_val,_s,C);
}
struct Treap{
node *root;
void init(){
root=Null;
}
void rot(node *&t,bool d){
node *p=t->c[d];t->c[d]=p->c[!d];
p->c[!d]=t;t->rz();p->rz();t=p;
}
void insert(node *&t,int val,int s){
if(t==Null){t=newnode(val,s,Null);return;}
if(t->val==val){t->s+=s;t->sum+=s;return;}
bool d=t->val<val;
insert(t->c[d],val,s);
if(t->c[d]->key<t->key)rot(t,d);
else t->rz();
}
int Qsum(node *t,int x){
int ans=0;
while(t!=Null){
if(t->val<=x)ans+=t->c[0]->sum+t->s,t=t->c[1];
else t=t->c[0];
}return ans;
}
void insert(int val,int s){insert(root,val,s);}
int Qsum(int l,int r){return Qsum(root,r)-Qsum(root,l-1);}
};
Treap d[maxn<<1];
inline int lowbit(int x){return x&-x;}
void updata(int x,int y,int z){
while(x<=k)d[x].insert(y,z),x+=lowbit(x);
}
int get(int x,int y){
int ans=0;
while(x)ans+=d[x].Qsum(1,y),x-=lowbit(x);
return ans;
}
int anss[maxn];
int getint(){
int res=0;char c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c))res=res*10+c-'0',c=getchar();
return res;
}
int main(){
Null=newnode(INT_MAX,0,0);
Null->key=INT_MAX;Null->c[0]=Null->c[1]=Null;
n=getint();k=getint();
for(int i=1;i<=k;i++)d[i].init();
for(int i=1;i<=n;i++)a[i].x=getint(),a[i].y=getint(),a[i].z=getint();
sort(a+1,a+1+n);
for(int i=1;i<=n;++i)
if(a[i]!=a[i-1])
b[++size]=a[i],b[size].s++;
else b[size].s++;
for(int i=1;i<=size;i++){
int ans=get(b[i].y,b[i].z);
anss[ans+b[i].s-1]+=b[i].s;
updata(b[i].y,b[i].z,b[i].s);
}for(int i=0;i<n;i++)printf("%d\n",anss[i]);
return 0;
}