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 }
3196: Tyvj 1730 二逼平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 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
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
4
3
4
9
HINT
1.n和m的数据范围:n,m<=50000
2.序列中每个数的数据范围:[0,1e8]
3.虽然原题没有,但事实上5操作的k可能为负数