bzoj3196: Tyvj 1730 二逼平衡树
来源:互联网 发布:流程优化小组 编辑:程序博客网 时间:2024/05/17 22:03
传送门
蛋疼树套树。
外层线段树维护区间。
内层treap维护数字出现情况。
打完这道我整个人都不好了。
#include<cstdio>#include<cstdlib>#include<iostream>#include<cmath>#include<cstring>#include<algorithm>#define N 200005#define M 3000005#define inf 0x3f3f3f3fusing namespace std;int n,m,sz,ans,fl,x,y,k;int a[N],rt[N];int ls[M],rs[M],rnd[M],v[M],s[M],w[M];void update(int k){ s[k]=s[ls[k]]+s[rs[k]]+w[k];}void rturn(int &k){ int t=ls[k]; ls[k]=rs[t]; rs[t]=k; s[t]=s[k]; update(k); k=t;}void lturn(int &k){ int t=rs[k]; rs[k]=ls[t]; ls[t]=k; s[t]=s[k]; update(k); k=t;}void insert(int &k,int num){ if (!k){ k=++sz; s[k]=w[k]=1; v[k]=num; rnd[k]=rand(); return; } s[k]++; if (num==v[k]) w[k]++; else if (num<v[k]){ insert(ls[k],num); if (rnd[ls[k]]<rnd[k]) rturn(k); } else{ insert(rs[k],num); if (rnd[rs[k]]<rnd[k]) lturn(k); }}void del(int &k,int num){ if (v[k]==num){ if (w[k]>1){ w[k]--; s[k]--; return; } if (ls[k]*rs[k]==0) k=ls[k]+rs[k]; else if (rnd[ls[k]]<rnd[rs[k]]){ rturn(k); del(k,num); } else{ lturn(k); del(k,num); } } else if (num<v[k]){ del(ls[k],num); s[k]--; } else{ del(rs[k],num); s[k]--; }}void build(int k,int l,int r,int x,int num){ insert(rt[k],num); if (l==r) return; int mid=(l+r)/2; if (x<=mid) build(k*2,l,mid,x,num); else build(k*2+1,mid+1,r,x,num);}void askrk(int k,int num){ if (!k) return; if (num==v[k]){ ans+=s[ls[k]]; return; } if (num<v[k]) askrk(ls[k],num); else{ ans+=s[ls[k]]+w[k]; askrk(rs[k],num); }}void getrk(int k,int l,int r,int x,int y,int num){ if (l==x&&r==y){ askrk(rt[k],num); return; } int mid=(l+r)/2; if (y<=mid) getrk(k*2,l,mid,x,y,num); else if (x>mid) getrk(k*2+1,mid+1,r,x,y,num); else getrk(k*2,l,mid,x,mid,num),getrk(k*2+1,mid+1,r,mid+1,y,num);}void getnum(int x,int y,int z){ int l=0,r=inf,s; while (l<=r){ int mid=(l+r)/2; ans=1; getrk(1,1,n,x,y,mid); if (ans<=z) l=mid+1,s=mid; else r=mid-1; } printf("%d\n",s);}void change(int k,int l,int r,int x,int num,int y){ del(rt[k],y); insert(rt[k],num); if (l==r) return; int mid=(l+r)/2; if (x<=mid) change(k*2,l,mid,x,num,y); else change(k*2+1,mid+1,r,x,num,y);}void pre(int k,int num){ if (!k) return; if (v[k]<num){ ans=max(ans,v[k]); pre(rs[k],num); } else pre(ls[k],num);}void suc(int k,int num){ if (!k) return; if (v[k]>num){ ans=min(ans,v[k]); suc(ls[k],num); } else suc(rs[k],num);}void askpre(int k,int l,int r,int x,int y,int num){ if (l==x&&r==y){ pre(rt[k],num); return; } int mid=(l+r)/2; if (y<=mid) askpre(k*2,l,mid,x,y,num); else if (x>mid) askpre(k*2+1,mid+1,r,x,y,num); else askpre(k*2,l,mid,x,mid,num),askpre(k*2+1,mid+1,r,mid+1,y,num);}void asksuc(int k,int l,int r,int x,int y,int num){ if (l==x&&r==y){ suc(rt[k],num); return; } int mid=(l+r)/2; if (y<=mid) asksuc(k*2,l,mid,x,y,num); else if (x>mid) asksuc(k*2+1,mid+1,r,x,y,num); else asksuc(k*2,l,mid,x,mid,num),asksuc(k*2+1,mid+1,r,mid+1,y,num);}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=1;i<=n;i++) build(1,1,n,i,a[i]); for (int i=1;i<=m;i++){ scanf("%d%d%d",&fl,&x,&y); if (fl!=3) scanf("%d",&k); if (fl==1){ ans=1; getrk(1,1,n,x,y,k); printf("%d\n",ans); } if (fl==2) getnum(x,y,k); if (fl==3){ change(1,1,n,x,y,a[x]); a[x]=y; } if (fl==4){ ans=0; askpre(1,1,n,x,y,k); printf("%d\n",ans); } if (fl==5){ ans=inf; asksuc(1,1,n,x,y,k); printf("%d\n",ans); } }}
0 0
- [Bzoj3196]Tyvj 1730 二逼平衡树
- BZOJ3196: Tyvj 1730 二逼平衡树
- [BZOJ3196]Tyvj 1730 二逼平衡树
- bzoj3196: Tyvj 1730 二逼平衡树
- bzoj3196: Tyvj 1730 二逼平衡树
- 【bzoj3196】Tyvj 1730 二逼平衡树
- bzoj3196 Tyvj 1730 二逼平衡树
- bzoj3196: Tyvj 1730 二逼平衡树
- 【bzoj3196】Tyvj 1730 二逼平衡树 树套树
- 【bzoj3196】【坑】Tyvj 1730 二逼平衡树 线段树套Treap/Splay
- bzoj3196 Tyvj 1730 二逼平衡树 线段树套treap
- bzoj3196 二逼平衡树
- Bzoj3196 二逼平衡树
- BZOJ3196 二逼平衡树
- BZOJ3196 二逼平衡树 Solution
- bzoj3196 tyvj1730 二逼平衡树
- BZOJ3196——二逼平衡树
- [树套树] BZOJ3196: 二逼平衡树
- 关于XML的解析的问题
- 2015蓝桥杯省赛模拟题C组
- Android菜单的使用
- 关于jsp中的tablib标签的定义与使用
- @JoinColumn 与mappedBy
- bzoj3196: Tyvj 1730 二逼平衡树
- 蓝桥杯历届——核桃数量
- Java设置图片背景
- [问题记录.WinDbg]在64位系统上抓取32位进程的dump
- 容器无法启动
- Win32 SDK学习笔记3
- STM32固件下载
- qsort函数、sort函数
- docker私有仓库搭建