首页 > 代码库 > BZOJ 3196 二逼平衡树
BZOJ 3196 二逼平衡树
为什么这么慢呢。。。。都是线段树套splay为什么就只能卡过去呢。。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 50050 #define maxm 4000050 #define inf 100000001 using namespace std; int n,m,tot1=0,tot2=0,tr_root,root[maxn<<2],ls[maxn<<2],rs[maxn<<2],tmp=0,x[maxn],mn[maxn<<2]; int tree[maxm][3],fath[maxm],size[maxm],cnt[maxm],val[maxm]; int type,l,r,pos,k; int pre,sub,tmp1,tmp2; void reset(int x) { root[x]=++tot2;tree[root[x]][2]=++tot2;fath[tot2]=root[x]; size[root[x]]=2;size[tot2]=1; val[root[x]]=-1;val[tot2]=inf;cnt[root[x]]=cnt[tot2]=1; } void pushup(int now) {size[now]=size[tree[now][1]]+size[tree[now][2]]+cnt[now];} void sg_build(int &now,int left,int right) { now=++tot1;reset(now);mn[now]=inf; if (left==right) return; int mid=left+right>>1; sg_build(ls[now],left,mid); sg_build(rs[now],mid+1,right); } void insert(int &now,int father,int k) { if (!now) { now=++tot2;fath[now]=father;size[now]=cnt[now]=1;val[now]=k; return; } if (val[now]==k) { cnt[now]++;size[now]++; return; } if (k<val[now]) insert(tree[now][1],now,k); else insert(tree[now][2],now,k); pushup(now); } void rotate(int x,int &k) { int y=fath[x],z=fath[y],l,r; if (tree[y][1]==x) l=1;else l=2;r=3-l; if (y==k) k=x; else { if (tree[z][1]==y) tree[z][1]=x; else tree[z][2]=x; } fath[x]=z;fath[y]=x;fath[tree[x][r]]=y; tree[y][l]=tree[x][r];tree[x][r]=y; pushup(y);pushup(x); } void splay(int x,int &k) { while (x!=k) { int y=fath[x],z=fath[y]; if (y!=k) { if ((tree[y][1]==x)^(tree[z][1]==y)) rotate(x,k); else rotate(y,k); } rotate(x,k); } } void sg_insert(int now,int left,int right,int pos,int k) { int ret=tot2; insert(root[now],0,k); if (ret!=tot2) splay(tot2,root[now]); if (left==right) return; int mid=left+right>>1; if (pos<=mid) sg_insert(ls[now],left,mid,pos,k); else sg_insert(rs[now],mid+1,right,pos,k); } void get_rank(int now,int k) { if (!now) return; if (val[now]<k) {tmp+=size[tree[now][1]]+cnt[now];get_rank(tree[now][2],k);} else if (val[now]==k) {tmp+=size[tree[now][1]];return;} else get_rank(tree[now][1],k); } void sg_get_rank(int now,int left,int right,int l,int r,int x) { if (left==l && right==r) {get_rank(root[now],x);tmp--;return;} int mid=left+right>>1; if (r<=mid) sg_get_rank(ls[now],left,mid,l,r,x); else if (l>=mid+1) sg_get_rank(rs[now],mid+1,right,l,r,x); else {sg_get_rank(ls[now],left,mid,l,mid,x);sg_get_rank(rs[now],mid+1,right,mid+1,r,x);} } int binary_search() { int left=0,right=inf-1,ans,mid; while (left<=right) { mid=left+right>>1;tmp=0; sg_get_rank(tr_root,1,n,l,r,mid); if (tmp+1<=k) {ans=mid;left=mid+1;} else right=mid-1; } return ans; } void find_pre(int now,int k) { if (!now) return; if (val[now]<k) {pre=now;find_pre(tree[now][2],k);} else find_pre(tree[now][1],k); } void find_sub(int now,int k) { if (!now) return; if (val[now]>k) {sub=now;find_sub(tree[now][1],k);} else find_sub(tree[now][2],k); } void delete_(int now,int k) { find_pre(root[now],k);find_sub(root[now],k); splay(pre,root[now]); splay(sub,tree[root[now]][2]); int x=root[now],y=tree[root[now]][2],z=tree[y][1]; if (cnt[z]>1) {cnt[z]--;size[z]--;} else fath[z]=tree[y][1]=0; pushup(y);pushup(x); } void sg_delete(int now,int left,int right,int pos,int k) { delete_(now,k); if (left==right) return; int mid=left+right>>1; if (pos<=mid) sg_delete(ls[now],left,mid,pos,k); else sg_delete(rs[now],mid+1,right,pos,k); } void sg_find_ps(int now,int left,int right,int l,int r,int k,int type) { if (left==l && right==r) { if (type==1) {find_pre(root[now],k);tmp1=max(tmp1,val[pre]);} else {find_sub(root[now],k);tmp2=min(tmp2,val[sub]);} return; } int mid=left+right>>1; if (r<=mid) sg_find_ps(ls[now],left,mid,l,r,k,type); else if (l>=mid+1) sg_find_ps(rs[now],mid+1,right,l,r,k,type); else {sg_find_ps(ls[now],left,mid,l,mid,k,type);sg_find_ps(rs[now],mid+1,right,mid+1,r,k,type);} } void sg_mn_modify(int now,int left,int right,int pos,int k) { if (left==right) {mn[now]=k;return;} int mid=(left+right)>>1; if (pos<=mid) sg_mn_modify(ls[now],left,mid,pos,k); else sg_mn_modify(rs[now],mid+1,right,pos,k); mn[now]=min(mn[ls[now]],mn[rs[now]]); } int sg_mn_ask(int now,int left,int right,int l,int r) { if (left==l && right==r) return mn[now]; int mid=(left+right)>>1; if (r<=mid) return sg_mn_ask(ls[now],left,mid,l,r); else if (l>=mid+1) return sg_mn_ask(rs[now],mid+1,right,l,r); else return min(sg_mn_ask(ls[now],left,mid,l,mid),sg_mn_ask(rs[now],mid+1,right,mid+1,r)); } int main() { scanf("%d%d",&n,&m); sg_build(tr_root,1,n); for (int i=1;i<=n;i++) { scanf("%d",&x[i]);k=x[i]; sg_insert(tr_root,1,n,i,k); sg_mn_modify(tr_root,1,n,i,k); } for (int i=1;i<=m;i++) { scanf("%d",&type); if (type==1) {scanf("%d%d%d",&l,&r,&k);tmp=0;sg_get_rank(tr_root,1,n,l,r,k);printf("%d\n",tmp+1);} else if (type==2) {scanf("%d%d%d",&l,&r,&k);printf("%d\n",binary_search());} else if (type==3) {scanf("%d%d",&pos,&k);sg_delete(tr_root,1,n,pos,x[pos]);x[pos]=k;sg_insert(tr_root,1,n,pos,k);sg_mn_modify(tr_root,1,n,pos,k);} else if (type==4) {scanf("%d%d%d",&l,&r,&k);tmp1=0;sg_find_ps(tr_root,1,n,l,r,k,1);printf("%d\n",tmp1);} else { scanf("%d%d%d",&l,&r,&k); if (k<0) printf("%d\n",sg_mn_ask(tr_root,1,n,l,r)); else { tmp2=inf; sg_find_ps(tr_root,1,n,l,r,k,2); printf("%d\n",tmp2); } } } return 0; }
BZOJ 3196 二逼平衡树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。