【BZOJ】【3262】陌上花开

树套树


  orz zyf

  这题的思路……算是让我了解到了树套树的一种用途吧

三维。。。第一维排序,第二维树状数组,第三维treap
具体实现就是每个树状数组的节点保存一颗treap,然后就可以查询了。
  好神啊……
  树套树可以方便的进行特殊的区间求和,大多数满足区间加法的运算都可以用树套树来搞,比如这题的对所有第二维坐标小于当前点(相当于一段前缀)求第三维坐标小于当前点的和。= =啊……就是一个特殊的前缀和嘛……
 
  还有就是这题其实有个K的……表示坐标的范围……所以树状数组要一直到k,而不是n
  1 /**************************************************************
  2     Problem: 3262
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:6728 ms
  7     Memory:99128 kb
  8 ****************************************************************/
  9  
 10 //BZOJ 3262
 11 #include<cmath>
 12 #include<vector>
 13 #include<cstdio>
 14 #include<cstring>
 15 #include<cstdlib>
 16 #include<iostream>
 17 #include<algorithm>
 18 #define rep(i,n) for(int i=0;i<n;++i)
 19 #define F(i,j,n) for(int i=j;i<=n;++i)
 20 #define D(i,j,n) for(int i=j;i>=n;--i)
 21 #define pb push_back
 22 #define CC(a,b) memset(a,b,sizeof(a))
 23 using namespace std;
 24 int getint(){
 25     int v=0,sign=1; char ch=getchar();
 26     while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();}
 27     while(isdigit(ch))  {v=v*10+ch-'0'; ch=getchar();}
 28     return v*sign;
 29 }
 30 const int N=210000,M=4000000,INF=~0u>>2;
 31 const double eps=1e-8;
 32 /*******************template********************/
 33 int n,k,tot,l[M],r[M],s[M],rnd[M],w[M],v[M];
 34 #define L l[x]
 35 #define R r[x]
 36 inline void Push_up(int x){ s[x]=s[L]+s[R]+w[x]; }
 37 inline void zig(int &x){int t=L; L=r[t]; r[t]=x; s[t]=s[x]; Push_up(x); x=t;}
 38 inline void zag(int &x){int t=R; R=l[t]; l[t]=x; s[t]=s[x]; Push_up(x); x=t;}
 39 void ins(int &x,int num,int z){
 40     if (!x){
 41         x=++tot; v[x]=num; s[x]=w[x]=z; L=R=0; rnd[x]=rand(); return;
 42     }
 43     s[x]+=z;
 44     if (v[x]==num) w[x]+=z;
 45     else if(num<v[x]){
 46         ins(L,num,z); if(rnd[L]<rnd[x]) zig(x);
 47     }else{
 48         ins(R,num,z); if(rnd[R]<rnd[x]) zag(x);
 49     }
 50 }
 51 int rank(int x,int num){
 52     if (!x) return 0;
 53     if (v[x]==num) return s[L]+w[x];
 54     else if(num<v[x]) return rank(L,num);
 55     else return s[L]+w[x]+rank(R,num);
 56 }
 57 #undef L
 58 #undef R
 59 /*********************Treap*********************/
 60 int rt[N];
 61 void update(int x,int y,int z){
 62     for(int i=x;i<=k;i+=i&-i) ins(rt[i],y,z);
 63 }
 64 int query(int x,int y){
 65     int ans=0;
 66     for(int i=x;i;i-=i&-i) ans+=rank(rt[i],y);
 67     return ans;
 68 }
 69 /*******************Fenwick*********************/
 70 struct data{
 71     int s,c,m;
 72 }a[N];
 73 bool cmp(data a,data b){
 74     if (a.s==b.s){
 75         if (a.c==b.c) return a.m<b.m;
 76         return a.c<b.c;
 77     }
 78     return a.s<b.s;
 79 }
 80 int ans[N];
 81 int main(){
 82 #ifndef ONLINE_JUDGE
 83     freopen("3262.in","r",stdin);
 84     freopen("3262.out","w",stdout);
 85 #endif
 86     n=getint(); k=getint();
 87     F(i,1,n){
 88         a[i].s=getint();
 89         a[i].c=getint();
 90         a[i].m=getint();
 91     }
 92     sort(a+1,a+n+1,cmp);
 93     int num=1;
 94     F(i,1,n){
 95         if (a[i].s==a[i+1].s &&
 96             a[i].c==a[i+1].c &&
 97             a[i].m==a[i+1].m) num++;
 98         else{
 99             ans[query(a[i].c,a[i].m)+num-1]+=num;
100             update(a[i].c,a[i].m,num);
101             num=1;
102         }
103     }
104     rep(i,n) printf("%d\n",ans[i]);
105     return 0;
106 }
View Code

 

posted @ 2015-03-16 23:03  Tunix  阅读(216)  评论(0编辑  收藏  举报