您的位置:首页 > 其它

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;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: