bzoj3196

树套树。。。。这个排名也真是坑爹。。。。加1会重复。。。

  1 #include<bits/stdc++.h>
  2 #define lowbit(a) ((a)&(-(a)))
  3 #define l(a) ((a)<<1)
  4 #define r(a) ((a)<<1|1)
  5 #define clr(a,x) memset(a,x,sizeof(a))
  6 #define rep(i,l,r) for(int i=l;i<(r);i++)
  7 typedef long long ll;
  8 using namespace std;
  9 int read()
 10 {
 11     char c=getchar();
 12     int ans=0,f=1;
 13     while(!isdigit(c)){
 14         if(c=='-') f=-1;
 15         c=getchar();
 16     }
 17     while(isdigit(c)){
 18         ans=ans*10+c-'0';
 19         c=getchar();
 20     }
 21     return ans*f;
 22 }
 23 const int maxnode=1500009,maxn=50009,maxm=50009,inf=0x7fffffff;
 24 int size=1;
 25 struct node{
 26     int l,r,s,g,w,v;
 27 };    
 28 node x[maxnode];
 29 struct treap{
 30     int root;
 31     treap(){
 32         root=0;
 33     }
 34     inline void maintain(int k){
 35         x[k].s=x[x[k].l].s+x[x[k].r].s+x[k].g;
 36     }
 37     inline void lrot(int&k){
 38         int t=x[k].r;
 39         x[k].r=x[t].l;
 40         x[t].l=k;
 41         x[t].s=x[k].s;
 42         maintain(k);
 43         k=t;
 44     }
 45     inline void rrot(int&k){
 46         int t=x[k].l;
 47         x[k].l=x[t].r;
 48         x[t].r=k;
 49         x[t].s=x[k].s;
 50         maintain(k);
 51         k=t;
 52     }
 53     inline void insert(int&k,int a){
 54         if(!k){    
 55             k=size;
 56             x[size].v=a;x[size].s=x[size].g=1;x[size++].w=rand();
 57             return;
 58         }
 59         ++x[k].s;
 60         if(a==x[k].v){
 61             ++x[k].g;return;
 62         }
 63         if(a>x[k].v){
 64             insert(x[k].r,a);
 65             if(x[x[k].r].w>x[k].w) lrot(k);
 66             return;
 67         }
 68         insert(x[k].l,a);
 69         if(x[x[k].l].w>x[k].w) rrot(k);
 70     }
 71     inline void del(int&k,int a){
 72         if(!k) return;
 73         if(x[k].v==a){
 74             if(x[k].g>1){
 75                 --x[k].g;--x[k].s;
 76                 return;
 77             }
 78             if(x[k].l*x[k].r==0) k=x[k].l+x[k].r;
 79             else if(x[x[k].l].w>x[x[k].r].w){
 80                 rrot(k);del(k,a);
 81             }
 82             else{
 83                 lrot(k);del(k,a);
 84             }
 85             return;
 86         }
 87         if(a>x[k].v) --x[k].s,del(x[k].r,a);
 88         else --x[k].s,del(x[k].l,a);
 89     }
 90     inline int rank(int k,int a){
 91         if(!k) return 0;
 92         if(x[k].v==a) return x[x[k].l].s;
 93         if(a>x[k].v) return x[x[k].l].s+x[k].g+rank(x[k].r,a);
 94         return rank(x[k].l,a);
 95     }
 96     inline int num(int k,int a){
 97         if(!k) return 0;
 98         if(a<=x[x[k].l].s) return num(x[k].l,a);
 99         if(a>x[x[k].l].s+x[k].g) return num(x[k].r,a-x[x[k].l].s-x[k].g);
100         return x[k].v;
101     }
102     inline int pre(int k,int a){
103         if(!k) return -1;
104         return x[k].v>=a?pre(x[k].l,a):max(x[k].v,pre(x[k].r,a));
105     }
106     inline int suc(int k,int a){
107         if(!k) return inf;
108         return x[k].v<=a?suc(x[k].r,a):min(x[k].v,suc(x[k].l,a));
109     }
110 };
111 struct Node{
112     int l,r;
113     treap t;
114 };
115 Node T[maxn<<2];
116 int a[maxn],mn=inf,mx=-inf;
117 void build(int k,int l,int r){
118     T[k].l=l;T[k].r=r;
119     rep(i,l,r+1) T[k].t.insert(T[k].t.root,a[i]);
120     if(l==r) return;
121     int mid=(l+r)>>1;
122     build(l(k),l,mid);
123     build(r(k),mid+1,r);
124 }
125 int Rank(int k,int l,int r,int t){
126     if(T[k].l==l&&T[k].r==r) return T[k].t.rank(T[k].t.root,t);
127     int mid=(T[k].l+T[k].r)>>1;
128     if(r<=mid) return Rank(l(k),l,r,t);
129     if(l>mid) return Rank(r(k),l,r,t);
130     return Rank(l(k),l,mid,t)+Rank(r(k),mid+1,r,t);
131 }
132 int Num(int k,int l,int r,int t){
133     if(T[k].l==l&&T[k].r==r) return T[k].t.num(T[k].t.root,t);
134     int L=mn,R=mx,ans;
135     while(L<=R){
136         int mid=(L+R)>>1;
137         if(Rank(1,l,r,mid)+1<=t) ans=mid,L=mid+1;
138         else R=mid-1;
139     }
140     return ans;
141 }
142 void Change(int k,int p,int t){
143     T[k].t.del(T[k].t.root,a[p]);
144     T[k].t.insert(T[k].t.root,t);
145     if(T[k].l==T[k].r) return;
146     int mid=(T[k].l+T[k].r)>>1;
147     Change(mid>=p?l(k):r(k),p,t);
148 }
149 int Pre(int k,int l,int r,int t){
150     if(T[k].l==l&&T[k].r==r) return T[k].t.pre(T[k].t.root,t);
151     int mid=(T[k].l+T[k].r)>>1;
152     if(r<=mid) return Pre(l(k),l,r,t);
153     if(l>mid) return Pre(r(k),l,r,t);
154     return max(Pre(l(k),l,mid,t),Pre(r(k),mid+1,r,t));
155 }
156 int Suc(int k,int l,int r,int t){
157     if(T[k].l==l&&T[k].r==r) return T[k].t.suc(T[k].t.root,t);
158     int mid=(T[k].l+T[k].r)>>1;
159     if(r<=mid) return Suc(l(k),l,r,t);
160     if(l>mid) return Suc(r(k),l,r,t);
161     return min(Suc(l(k),l,mid,t),Suc(r(k),mid+1,r,t));
162 }
163 int main()
164 {    
165     int n=read(),m=read();
166     rep(i,1,n+1) a[i]=read(),mn=min(mn,a[i]),mx=max(mx,a[i]);
167     build(1,1,n);
168     while(m--){
169         int opt=read(),l=read(),r=read(),t;
170         if(opt!=3) t=read();
171         if(opt==1) printf("%d\n",Rank(1,l,r,t)+1);
172         else if(opt==2) printf("%d\n",Num(1,l,r,t));
173         else if(opt==3) Change(1,l,r),a[l]=r,mn=min(mn,r),mx=max(mx,r);
174         else if(opt==4) printf("%d\n",Pre(1,l,r,t));
175         else printf("%d\n",Suc(1,l,r,t));
176     }
177     return 0;
178 }
View Code

3196: Tyvj 1730 二逼平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 1368  Solved: 583
[Submit][Status][Discuss]

Description

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
1.查询k在区间内的排名
2.查询区间内排名为k的值
3.修改某一位值上的数值
4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
5.查询k在区间内的后继(后继定义为大于x,且最小的数)

Input

第一行两个数 n,m 表示长度为n的有序序列和m个操作
第二行有n个数,表示有序序列
下面有m行,opt表示操作标号
若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名
若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数
若opt=3 则为操作3,之后有两个数pos,k 表示将pos位置的数修改为k
若opt=4 则为操作4,之后有三个数l,r,k 表示查询区间[l,r]内k的前驱
若opt=5 则为操作5,之后有三个数l,r,k 表示查询区间[l,r]内k的后继

Output

对于操作1,2,4,5各输出一行,表示查询结果

Sample Input

9 6
4 2 2 1 9 4 0 1 1
2 1 4 3
3 4 10
2 1 4 3
1 2 5 9
4 3 9 5
5 2 8 5

Sample Output

2
4
3
4
9

HINT

 

1.n和m的数据范围:n,m<=50000


2.序列中每个数的数据范围:[0,1e8]


3.虽然原题没有,但事实上5操作的k可能为负数

 

Source

 
[Submit][Status][Discuss]
posted @ 2015-08-20 15:01  ChenThree  阅读(147)  评论(0编辑  收藏  举报