码迷,mamicode.com
首页 > 其他好文 > 详细

【BZOJ】【3262】陌上花开

时间:2015-03-17 00:39:18      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:

树套树


  orz zyf

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

三维。。。第一维排序,第二维树状数组,第三维treap
具体实现就是每个树状数组的节点保存一颗treap,然后就可以查询了。
  好神啊……
  树套树可以方便的进行特殊的区间求和,大多数满足区间加法的运算都可以用树套树来搞,比如这题的对所有第二维坐标小于当前点(相当于一段前缀)求第三维坐标小于当前点的和。= =啊……就是一个特殊的前缀和嘛……
技术分享
  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

 

【BZOJ】【3262】陌上花开

标签:

原文地址:http://www.cnblogs.com/Tunix/p/4343211.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!