bzoj3196(线段树套treap)
2016-01-21 20:28
375 查看
#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<string>#include<cmath>#include<ctime>#include<queue>#include<stack>#include<map>#include<set>#define rre(i,r,l) for(int i=(r);i>=(l);i--)#define re(i,l,r) for(int i=(l);i<=(r);i++)#define Clear(a,b) memset(a,b,sizeof(a))#define inout(x) printf("%d",(x))#define douin(x) scanf("%lf",&x)#define strin(x) scanf("%s",(x))#define LLin(x) scanf("%lld",&x)#define op operator#define CSC maintypedef unsigned long long ULL;typedef const int cint;typedef long long LL;using namespace std;cint inf=100000000;void inin(int &ret){ret=0;int f=0;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar();ret=f?-ret:ret;}int ch[2000050][2],c[2000050],s[2000050],rr[2000050],w[2000020],ed;struct segtree{int l,r,root;segtree(){root=0;}void maintain(int k){if(k)s[k]=c[k]+s[ch[k][0]]+s[ch[k][1]];}void rotate(int &k,int d){int p=ch[k][d^1];ch[k][d^1]=ch[p][d];ch[p][d]=k;s[p]=s[k];maintain(k),k=p;}private:void add(int &k,const int &x){if(!k){k=++ed,w[k]=x,rr[k]=rand();s[k]=c[k]=1;ch[k][0]=ch[k][1]=0;return ;}s[k]++;if(x==w[k]){c[k]++;return ;}int d=x>w[k];add(ch[k][d],x);if(rr[ch[k][d]]<rr[k])rotate(k,d^1);}bool del(int &k,const int &x){if(!k)return 0;if(x==w[k]){if(c[k]>1){c[k]--,s[k]--;return 1;}if(!ch[k][0]){k=ch[k][1];return 1;}if(!ch[k][1]){k=ch[k][0];return 1;}if(rr[ch[k][0]]<rr[ch[k][1]])rotate(k,1);else rotate(k,0);return del(k,x);}int d=x>w[k];if(del(ch[k][d],x)){s[k]--;return 1;}else return 0;}int findrank(int k,const int &x){if(!k)return 0;int pp=(ch[k][0]?s[ch[k][0]]:0);if(x==w[k])return pp;if(x>w[k])return pp+c[k]+findrank(ch[k][1],x);return findrank(ch[k][0],x);}int findwei(int k,const int &x){if(!k)return 0;int pp=(ch[k][0]?s[ch[k][0]]:0);if(x<=pp)return findwei(ch[k][0],x);if(x>pp+c[k])return findwei(ch[k][1],x-pp-c[k]);return w[k];}void findqian(int k,const int &x,int &ans){if(!k)return ;if(x>w[k])ans=w[k],findqian(ch[k][1],x,ans);else findqian(ch[k][0],x,ans);}void findhou(int k,const int &x,int &ans){if(!k)return ;if(x<w[k])ans=w[k],findhou(ch[k][0],x,ans);else findhou(ch[k][1],x,ans);}public:void add(int x){add(root,x);}void del(int x){del(root,x);}int findrank(int x){return findrank(root,x);}int findwei(int x){return findwei(root,x);}int findqian(int x){int ans=0;findqian(root,x,ans);return ans;}int findhou(int x){int ans=0;findhou(root,x,ans);return !ans?inf:ans;}}t[200020];int qi[50050];void build(int k,int l,int r,int x){t[k].l=l,t[k].r=r,t[k].add(qi[x]);if(l==r)return ;int mid=(l+r)>>1;if(x<=mid)build(k<<1,l,mid,x);else build(k<<1|1,mid+1,r,x);}int findrank(int k,int l,int r,int x){if(t[k].l>=l&&t[k].r<=r)return t[k].findrank(x);int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1;if(r<=mid)return findrank(p1,l,r,x);if(l>mid)return findrank(p2,l,r,x);return findrank(p1,l,r,x)+findrank(p2,l,r,x);}int findqian(int k,int l,int r,int x){if(t[k].l>=l&&t[k].r<=r)return t[k].findqian(x);int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1;if(r<=mid)return findqian(p1,l,r,x);if(l>mid)return findqian(p2,l,r,x);return max(findqian(p1,l,r,x),findqian(p2,l,r,x));}int findhou(int k,int l,int r,int x){if(t[k].l>=l&&t[k].r<=r)return t[k].findhou(x);int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1;if(r<=mid)return findhou(p1,l,r,x);if(l>mid)return findhou(p2,l,r,x);return min(findhou(p1,l,r,x),findhou(p2,l,r,x));}int findwei(int l,int r,int x){int ll=0,rr=inf,mid,ans;while(ll<=rr){mid=(ll+rr)>>1;int rank=findrank(1,l,r,mid)+1;if(rank<=x)ans=mid,ll=mid+1;else rr=mid-1;}return findqian(1,l,r,ans+1);}void change(int k,int x,int w){t[k].del(qi[x]),t[k].add(w);if(t[k].l==t[k].r)return ;int mid=(t[k].l+t[k].r)>>1;if(x<=mid)change(k<<1,x,w);else change(k<<1|1,x,w);}int n,m;int CSC(){freopen("in.in","r",stdin);freopen("out.out","w",stdout);inin(n),inin(m);re(i,1,n)inin(qi[i]);re(i,1,n)build(1,1,n,i);re(i,1,m){int opt,q,ww,e;inin(opt);if(opt==1){inin(q),inin(ww),inin(e);printf("%d\n",findrank(1,q,ww,e)+1);}else if(opt==2){inin(q),inin(ww),inin(e);printf("%d\n",findwei(q,ww,e));}else if(opt==3){inin(q),inin(ww);change(1,q,ww);qi[q]=ww;}else if(opt==4){inin(q),inin(ww),inin(e);printf("%d\n",findqian(1,q,ww,e));}else{inin(q),inin(ww),inin(e);int ret=findhou(1,q,ww,e);// printf("%d\n",ret==inf?0:ret);printf("%d\n",ret);}}return 0;}
相关文章推荐
- 05-SCP&SFTP
- CentOS 7源码安装LNMP环境
- 跨域 上传文件 的一个例子
- Java程序员修练之道
- <LeetCode OJ> 22. Generate Parentheses
- Mysql命令大全
- javascript 显示类型转换
- 重拾编程之路--map遍历的四种方式
- CentOS和Ubuntu设置或修改网络配置(IP&网关&DNS)
- 网络请求--Retrofit2使用方法
- 【装载】Hough变换原理
- memcached和MySQL的query cache相比
- Keil - 编译错误总结 01
- 用win 7 32位 cmake2.8+VTK6.2+VS2012配置
- 记录一下,linux工程调试开发应用!
- 第001讲-Spark内核解密:Spark五大功能组件
- 日本医学专家提出杀死癌细胞新方法---简单!人人都可轻松做到
- 使用platform密钥对apk进行签名
- Java基础01 从HelloWorld到面向对象
- java多线程之(sleep)