BZOJ3262 陌上花开

来源:互联网 发布:linux expect 详解 编辑:程序博客网 时间:2024/04/29 09:57

以前的树套树第一题,好像也是除了二维线段树和二维bit的唯一一道树套树。

三维偏序是很裸的cdq,注意排序时,一是cdq里面sort的时候不能说按x为第一关键字就只比较第一关键字,这可能导致y1处的修改在y2的询问后面(y1<=y2),第二个是用重载的 < 比cmp快很多很多,把cdq里面的cmp去了之后快了1s。

//QWsin #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=100000+10; const int maxk=200000+10; inline int read() {     int ret=0;char ch=getchar();         while(ch<'0'||ch>'9') ch=getchar();     for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0';     return ret; } int n,k; struct Node{     int x,y,z,t,id;     inline void input(int i){id=i;x=read();y=read();z=read();}       bool operator != (const Node &rhs)const{         return  x!=rhs.x||y!=rhs.y||z!=rhs.z;     }     inline bool operator < (const Node &rhs)const{         if(y!=rhs.y) return y<rhs.y;         if(x!=rhs.x) return x<rhs.x;         return z<rhs.z;     } }x[maxn],t[maxn]; int ans[maxn],cnt[maxn],num[maxn]; int cmp1(Node a,Node b){     if(a.x!=b.x) return a.x<b.x;     if(a.y!=b.y) return a.y<b.y;     return a.z<b.z; } int id[maxn]; int C[maxk]; #define lowbit(i) ((i)&-(i)) inline void updata(int pos,int val){     for(int i=pos;i<=k;i+=lowbit(i)) C[i]+=val;   } inline int query(int pos){     int ret=0;     for(int i=pos;i;i-=lowbit(i)) ret+=C[i];     return ret;  } void solve(int l,int r) {     if(l>=r) return ;     int mid=(l+r)>>1;     solve(l,mid);     solve(mid+1,r);     for(int i=l;i<=mid;++i) x[i].t=0;     for(int i=mid+1;i<=r;++i) x[i].t=1;     for(int i=l;i<=r;++i) t[i]=x[i];     sort(t+l,t+r+1);     for(int i=l;i<=r;++i)         if(!t[i].t) updata(t[i].z,num[t[i].id]);         else ans[t[i].id]+=query(t[i].z);     for(int i=l;i<=r;++i)          if(!x[i].t) updata(x[i].z,-num[x[i].id]); } char s[20];int p; inline void output(int x){     if(!x) {putchar('0');}     else{         for(p=0;x;x/=10) s[++p]=x%10+'0';         for(int i=p;i>=1;--i) putchar(s[i]);     }     putchar('\n'); } int main() {     cin>>n>>k;     for(int i=1;i<=n;++i) t[i].input(i);     sort(t+1,t+n+1,cmp1);     int p=0;     for(int i=1;i<=n;++i)      {         if(i==1||t[i]!=t[i-1]) x[++p]=t[i],num[p]=1,x[p].id=p;         else ++num[p];     }     solve(1,p);     for(int i=1;i<=n;++i) cnt[ans[i]+num[i]-1]+=num[i];     for(int i=0;i<n;++i) output(cnt[i]);     return 0; } 
0 0