uestc 1425 Another LCIS(成段更新)
来源:互联网 发布:抗日主力的真相 知乎 编辑:程序博客网 时间:2024/05/09 10:15
题意:有T(t<10)组数据,给你N个数,M个操作(N和M都小于100000)。操作有两种类型,(1)“q a b”,查询区间[a,b]里的最长连续上升序列的长度。(2)“a l r v”,将区间[l,r]里的数全部增加v。
要记录区间里的最长的序列长度是多少,用mx来记录。由于最长的连续上升序列可以在区间的左端点,右端点,所以在线段树里增加两个域lmx和rmx,分别表示,在区间的端点处,分别向右向左的最长的满足条件的序列长度。但是还有可能出现在中间,所以又增加两个域lval和rval,分别表示区间端点的值是多少。合并的时候,判断左儿子的rval是否小于右儿子lval,如果满足,这个区间的mx可能为左儿子的rmx加上右儿子的lmx。另外,这个区间的mx可能是左儿子的mx或者右儿子的mx。
在更新当前区间的lmx时,如果左子区间的lmx等于左子区间的长度,那么当前区间的lmx就要加上右儿子的lmx。更新当前区间的rmx时同理。
另外在查询的时候,要注意,有可能当前区间的lmx大于mid-st+1,所以要在其中取一个较小值,同理rmx有可能大于ed-mid。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define LL(x) (x<<1) #define RR(x) (x<<1|1) #define MID(a,b) (a+((b-a)>>1)) const int N=100005; struct node { int lft,rht; int lmx,rmx,mx; int lval,rval,add; void fun(int tmp) { add+=tmp; lval+=tmp; rval+=tmp; } int len(){return rht-lft+1;} int mid(){return MID(lft,rht);} void init(){ lmx=rmx=mx=add=0; } }; int y[N],n,m; struct Segtree { node tree[N*4]; void down(int ind) { if(tree[ind].add) { tree[LL(ind)].fun(tree[ind].add); tree[RR(ind)].fun(tree[ind].add); tree[ind].add=0; } } void up(int ind) { tree[ind].lmx=tree[LL(ind)].lmx; tree[ind].rmx=tree[RR(ind)].rmx; tree[ind].lval=tree[LL(ind)].lval; tree[ind].rval=tree[RR(ind)].rval; tree[ind].mx=max(tree[LL(ind)].mx,tree[RR(ind)].mx); if(tree[LL(ind)].rval<tree[RR(ind)].lval) { if(tree[LL(ind)].lmx==tree[LL(ind)].len()) tree[ind].lmx+=tree[RR(ind)].lmx; if(tree[RR(ind)].rmx==tree[RR(ind)].len()) tree[ind].rmx+=tree[LL(ind)].rmx; tree[ind].mx=max(tree[ind].mx,tree[LL(ind)].rmx+tree[RR(ind)].lmx); } tree[ind].mx=max(tree[ind].mx,max(tree[ind].lmx,tree[ind].rmx)); } void build(int lft,int rht,int ind) { tree[ind].lft=lft; tree[ind].rht=rht; tree[ind].init(); if(lft==rht) { tree[ind].lval=tree[ind].rval=y[lft]; tree[ind].lmx=tree[ind].rmx=tree[ind].mx=1; } else { int mid=tree[ind].mid(); build(lft,mid,LL(ind)); build(mid+1,rht,RR(ind)); up(ind); } } void updata(int st,int ed,int ind,int valu) { int lft=tree[ind].lft,rht=tree[ind].rht; if(st<=lft&&rht<=ed) tree[ind].fun(valu); else { down(ind); int mid=tree[ind].mid(); if(st<=mid) updata(st,ed,LL(ind),valu); if(ed> mid) updata(st,ed,RR(ind),valu); up(ind); } } int query(int st,int ed,int ind) { int lft=tree[ind].lft,rht=tree[ind].rht; if(st<=lft&&rht<=ed) return tree[ind].mx; else { down(ind); int mid=tree[ind].mid(); if(ed<=mid) return query(st,ed,LL(ind)); else if(st>mid) return query(st,ed,RR(ind)); else { int mid=tree[ind].mid(); int mx1=query(st,ed,LL(ind)); int mx2=query(st,ed,RR(ind)); int tmp1=0,tmp2=0; if(tree[LL(ind)].rval<tree[RR(ind)].lval) { tmp1=min(mid-st+1,tree[LL(ind)].rmx); tmp2=min(ed-mid,tree[RR(ind)].lmx); } return max(max(mx1,mx2),tmp1+tmp2); } } } }seg; int main() { int t,t_cnt=0; scanf("%d",&t); while(t--) { char str[10]; int a,b,c; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&y[i]); seg.build(1,n,1); printf("Case #%d:\n",++t_cnt); while(m--) { scanf("%s",str); if(str[0]=='q') { scanf("%d%d",&a,&b); printf("%d\n",seg.query(a,b,1)); } else { scanf("%d%d%d",&a,&b,&c); seg.updata(a,b,1,c); } } } return 0; }
- uestc 1425 Another LCIS(成段更新)
- UESTC 1425 Another LCIS
- UESTC 1425 Another LCIS
- UESTC - 1425 Another LCIS
- UESTC 1425 Another LCIS
- UESTC 360(1425) another LCIS
- [UESTC]Another LCIS[线段树][区间合并][成段修改]
- uestc Another LCIS(区间更新,区间合并)
- UESTC 360 Another LCIS(线段树区间更新)
- uestc 1425 Another LCIS(线段树 最长递增序列)
- uestc 1425——Another LCIS
- 【37.07%】【UESTC 360】Another LCIS
- uestc Another LCIS 区间线段树
- UESTC 360 Another LCIS 线段树
- UESTC 360 Another LCIS (线段树 维护LCIS)
- uestc 1546 Bracket Sequence (成段更新)
- UESTC 1546(线段树,成段更新,区间合并)
- UESTC 1546 Bracket Sequence(线段树 成段更新)
- ubuntu10.04 下 eclipse 小结
- POJ 1276 Cash Machine
- SQL PASS西雅图之行——Lake Union纪行
- [第一份题解]负数进制转换
- access数据库备份与还原问题
- uestc 1425 Another LCIS(成段更新)
- 一些减肥的理论
- 一些减肥的食谱
- 【NFS服务配置实例】
- 【SuSe11.1 上架设NFS服务器】
- asp .net textbox实现点击文本消失
- 考研路_数据结构_查找2_插值查找和斐波那契查找
- 【SUSE Linux+NFS设置】
- 最大连续子序列求和详解