标签:const line break register include 分治 query main ++i
https://www.luogu.org/problemnew/show/3810
CDQ分治棵题
第一维 排序
第二维 CDQ分治
第三位 树状数组维护
#include<stdio.h>
#include<algorithm>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
using std::sort;
const int N=100011;
struct point{
int x,y,z,sum,cnt;
inline bool operator ==(const point &B)const{
return x==B.x&&y==B.y&&z==B.z;
}
inline bool operator <(const point &B)const{
if(x!=B.x)return x<B.x;
if(y!=B.y)return y<B.y;
return z<B.z;
}
inline bool operator >(const point &B)const{
if(y!=B.y)return y<B.y;
return z<=B.z;
}
}t[N],a[N];
int n,k;
int tr[N<<1],ans[N<<1];
inline void add(int p,int v){
for(;p<=k;p+=p&(-p))tr[p]+=v;
}
inline int query(int p){
int ret=0;
for(;p;p-=p&(-p))ret+=tr[p];
return ret;
}
inline void del(int p){
for(;p<=k;p+=p&(-p))
if(tr[p])tr[p]=0;
else break;
}
inline void cdq(int l,int r){
if(l==r)return;
int mid=(l+r)>>1;
int idx1=l,idx2=mid+1;
cdq(l,mid);cdq(mid+1,r);
FOR(i,l,r){
if(idx2>r||(idx1<=mid&&a[idx1]>a[idx2])){
t[i]=a[idx1++];
add(t[i].z,t[i].cnt);
}
else{
t[i]=a[idx2++];
t[i].sum+=query(t[i].z);
}
}
FOR(i,l,r){
a[i]=t[i];
del(a[i].z);
}
return;
}
int main(){
scanf("%d%d",&n,&k);
FOR(i,1,n)scanf("%d%d%d",&t[i].x,&t[i].y,&t[i].z);
sort(t+1,t+n+1);
register int head=1,m=0,tail=0;
while(head<=n){
tail=head+1;
while(tail<=n&&t[head]==t[tail])++tail;
a[++m]=t[head];a[m].cnt=tail-head;
head=tail;
}
cdq(1,m);
FOR(i,1,m)
ans[a[i].sum+a[i].cnt]+=a[i].cnt;
FOR(i,1,n)
printf("%d\n",ans[i]);
return 0;
}
标签:const line break register include 分治 query main ++i
原文地址:http://www.cnblogs.com/Stump/p/7906316.html