数据结构:线段树——区间最长连续子序列
2020-07-26 22:04
148 查看
/* 线段树维护区间最长连续子序列 */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=5e4+10; struct node{ int l,r,sum;//从左边开始往右的最长连续子序列长度,从右边开始往左的最长连续子序列长度,整段区间之和 }t[maxn<<2]; int n,m; void pushup(int l,int r,int rt){ int m=l+r>>1; t[rt].l=t[rt<<1].l+(t[rt<<1].l==m-l+1 ? t[rt<<1|1].l : 0);//若左子树的最长连续子序列长度等于左子树整段的长度则还要加上右子树的从左开始的最长连续子序列 t[rt].r=t[rt<<1|1].r+(t[rt<<1|1].r==r-m ? t[rt<<1].r : 0); t[rt].sum=max(max(t[rt<<1].sum,t[rt<<1|1].sum),t[rt<<1].r+t[rt<<1|1].l); } void build(int l,int r,int rt){ if(l==r){ t[rt].l=t[rt].r=t[rt].sum=1; return; } int m=(l+r)>>1; build(l,m,rt<<1); build(m+1,r,rt<<1|1); pushup(l,r,rt); } void update(int pos,int v,int l,int r,int rt){ if(l==r){ t[rt].l=t[rt].r=t[rt].sum=v; return ; } int m=(l+r)>>1; if(pos<=m) update(pos,v,l,m,rt<<1); else update(pos,v,m+1,r,rt<<1|1); pushup(l,r,rt); } int query(int pos,int l,int r,int rt){ if(l==r || t[rt].sum==0 || t[rt].sum==r-l+1){ return t[rt].sum; } int m=l+r>>1; if(pos<=m){ if(m-t[rt<<1].r+1<=pos) return t[rt<<1].r+t[rt<<1|1].l; else return query(pos,l,m,rt<<1); } else { if(t[rt<<1|1].l+m>=pos) return t[rt<<1].r+t[rt<<1|1].l; else return query(pos,m+1,r,rt<<1|1); } } int main(){ while(~scanf("%d%d",&n,&m)){ build(1,n,1); char c; int a[maxn]; int cnt=0,x; for (int i=1;i<=m;i++){ getchar(); scanf("%c",&c); if(c=='D'){ scanf("%d",&x); a[cnt++]=x; update(x,0,1,n,1); } else if(c=='Q'){ scanf("%d",&x); int ans=query(x,1,n,1); printf("%d\n",ans); } else if(c=='R'){ update(a[--cnt],1,1,n,1); } } } return 0; }
相关文章推荐
- HDU 3308——LCIS(线段树,区间合并,最长连续递增子序列)
- 线段树区间合并+最长连续递增子序列——HDU 3308
- HDU 3308 线段树单点更新+区间查找最长连续子序列
- HDU 3308 LCIS(最长连续上升子序列)(线段树区间合并)
- hdu 3308 线段树-区间连续最长上升子序列
- 【维护区间最长连续子序列 && 线段树 && 区间归并】HDU - 1540 Tunnel Warfare
- 数据结构1 「在线段树中查询一个区间的复杂度为 $O(\log N)$」的证明
- PKU 3667 Hotel (线段树,区间合并,最长连续区间)
- PKU 3667 Hotel (线段树,区间合并,最长连续区间)
- HDU 3308 线段树 最长连续上升子序列 单点更新 区间查询
- hdu3308 LCIS--区间更新 & 最长连续上升子序列
- hdu 1540 Tunnel Warfare (线段树维护左右最长连续区间)
- HDU 3308 线段树 最长连续上升子序列 单点更新 区间查询
- HDU 3308 线段树。。最长连续上升子序列
- hdu 1540 Tunnel Warfare (线段树维护左右最长连续区间)
- CUGB专题训练之数据结构:B - Count Color 线段树区间更新
- HDU 3308 LCIS(线段树+区间合并+最长递增连续子串)
- 数据结构之线段树(区间树,Segment Tree)
- HDU-4553-约会安排(线段树维护最长连续区间)
- nyoj 17 数据结构 最长单调递增子序列