PKU2892(Tunnel Warfare)线段树求最大连续区间
2013-03-12 17:07
393 查看
/************************************** 题目大意: 一条直线上的有n个顶点; (1)D x 破坏顶点x; (2)Q x 表示查询以x所在的最长的连续的点的个数,包括顶点x本身; (3)R 修复上一次被破坏的点; 算法思想: 线段树,求最大连续区间,操作类似于pku3667; ls 记录区间左端点开始的最大连续个数, rs 记录区间右端点开始的最大的连续个数, ms 表示该区间最大的连续点的个数。 ***************************************/ #include<iostream> #include<algorithm> #include<stack> #include<cstring> #include<cstdlib> #include<cstdio> using namespace std; #define L l,m,u<<1 #define R m+1,r,u<<1|1 const int N=50050; int st ;//模拟栈序列 int top;//模拟栈顶元素 struct Node { int l,r; int ls,rs,ms;//ls:左边开始连续的最大长度;rs:右边开始最大的连续长度;ms:这个区间最大连续长度; } T[N*3]; void build(int l,int r,int u) { T[u].l=l; T[u].r=r; T[u].ls=T[u].rs=T[u].ms=r-l+1; if(l==r) return; int m=(l+r)>>1; build(L); build(R); } void update(int u,int t,int x) { if(T[u].l==T[u].r) { if(x==1) T[u].ls=T[u].rs=T[u].ms=1; else T[u].ls=T[u].rs=T[u].ms=0; return; } int m=(T[u].l+T[u].r)>>1; if(t<=m) update(u<<1,t,x); else update(u<<1|1,t,x); T[u].ls=T[u<<1].ls; T[u].rs=T[u<<1|1].rs; T[u].ms=max(T[u<<1].ms,T[u<<1|1].ms); T[u].ms=max(T[u].ms,T[u<<1].rs+T[u<<1|1].ls); if(T[u<<1].ls==T[u<<1].r-T[u<<1].l+1) T[u].ls+=T[u<<1|1].ls; if(T[u<<1|1].rs==T[u<<1|1].r-T[u<<1|1].l+1) T[u].rs+=T[u<<1].rs; } int query(int u,int t) { if(T[u].l==T[u].r||T[u].ms==0||T[u].ms==T[u].r-T[u].l+1) { return T[u].ms; } int m=(T[u].l+T[u].r)>>1; if(t<=m) { if(t>=T[u<<1].r-T[u<<1].rs+1) return query(u<<1,t)+query(u<<1|1,m+1); else return query(u<<1,t); } else { if(t<=T[u<<1|1].l+T[u<<1|1].ls-1) return query(u<<1|1,t)+query(u<<1,m); else return query(u<<1|1,t); } } int main() { //freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin); int n,m; while(~scanf("%d%d",&n,&m)) { build(1,n,1); top=0; while(m--) { char c; int x; scanf(" %c",&c); if(c=='D') { scanf("%d",&x); st[top++]=x; update(1,x,0); } else if(c=='Q') { scanf("%d",&x); printf("%d\n",query(1,x)); } else { if(x>0) { x=st[--top]; update(1,x,1); } } } } return 0; }
相关文章推荐
- POJ 题目2892 Tunnel Warfare(线段树单点更新查询,求单点所在最大连续区间长度)
- HDU - 1540 Tunnel Warfare(线段树最大连续区间)
- HDU 1540 Tunnel Warfare(线段树,去最大连续区间)
- HDU 1540 Tunnel Warfare 【线段树--最大连续区间】
- HDU 1540 Tunnel Warfare(线段树 区间合并 最大连续区间)
- poj 2892 hdu1540 线段树 求过某点的最大连续区间。
- poj 2892 Tunnel Warfare 查询从x开始向左右能到达的最大区间 线段树
- ZOJ 2301 / HDU 1199 Color the Ball 离散化+线段树区间连续最大和
- !SPOJ 1043 多次查询区间最大连续和-线段树
- PKU 3667 Hotel (线段树,区间合并,最长连续区间)
- HDU 1540(线段树,以一点扩展开的最大连续区间)
- Hdu 1540 求连续区间最大值的线段树
- Vijos 题目P1083小白逛公园(线段树,区间连续最大和)
- LA3938-Ray, Pass me the dishes!--动态最大连续区间和(线段树+前后缀数和组)
- poj 2892 Tunnel Warfare(线段树 单点更新 区间合并)
- UVA 3938 线段树(连续最大值区间)
- UVALive - 3938 Ray, Pass methe dishes!"(动态最大连续和子序列,线段树区间合并)
- poj2750-Potted Flower-动态求最大连续环区间和(线段树上分治+set维护)
- hdu 1540 线段树 点所在的区间最大连续长度
- poj 1750Potted Flower(线段树 区间合并 动态规划 区间求最大连续和)