标签:lcis hdu 3308 given n integers you have two operati hdu
刚刚做了两道LCIS,碰到这道线段树,脑抽了似的写 线段树+dp(LCIS),贡献一发TLE。
才想到要区间合并,query函数写了好久。下面有详细注释,参见代码吧~~欢迎点赞,欢迎卖萌~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308
#include<cstdio> #include<cstring> #include<algorithm> #define N 111111 #define lson rt<<1,s,m #define rson rt<<1|1,m+1,e using namespace std; struct node{ int lv,rv; // 维护一个区间的左端点值和右端点值。 int lm,rm,sm; //左LCIS,右LCIS,整个区间LCIS。 }tre[N<<2]; void pushup(int rt,int m) //区间合并。 { tre[rt].lm=tre[rt<<1].lm; tre[rt].rm=tre[rt<<1|1].rm; tre[rt].lv=tre[rt<<1].lv; tre[rt].rv=tre[rt<<1|1].rv; tre[rt].sm=max(tre[rt<<1].sm,tre[rt<<1|1].sm); //1~~ //左儿子的右端点值小于右儿子的左端点值,最长LCIS可能在中间区域。 if(tre[rt<<1].rv < tre[rt<<1|1].lv) { tre[rt].sm=max(tre[rt].sm,tre[rt<<1].rm+tre[rt<<1|1].lm);//2~~ if(tre[rt<<1].lm == m-(m>>1)) tre[rt].lm += tre[rt<<1|1].lm; if(tre[rt<<1|1].rm == (m>>1)) tre[rt].rm += tre[rt<<1].rm; } } void build(int rt,int s,int e) { if(s==e) { scanf("%d",&tre[rt].lv); tre[rt].rv=tre[rt].lv; tre[rt].lm=tre[rt].rm=tre[rt].sm=1; return ; } int m=(s+e)>>1; build(lson); build(rson); pushup(rt,e-s+1); } void update(int p,int v,int rt,int s,int e) { if(s==e) { tre[rt].lv=tre[rt].rv=v; //端点更新。 return ; } int m=(s+e)>>1; if(p<=m) update(p,v,lson); else update(p,v,rson); pushup(rt,e-s+1); } int query(int l,int r,int rt,int s,int e) { if(l<=s && e<=r) return tre[rt].sm; int m=(s+e)>>1; if(r<=m) return query(l,r,lson); else if(l>m) return query(l,r,rson); else { int ans=-1; if(tre[rt<<1].rv < tre[rt<<1|1].lv) //~~ { //左儿子右LCIS的左边界。 int L=m-tre[rt<<1].rm+1; //右儿子左LCIS的右边界。 int R=m+1+tre[rt<<1|1].lm-1; ans=min(R,r)-max(L,l)+1; } return max(query(l,m,lson),max(query(m+1,r,rson),ans)); } } int main() { int T; scanf("%d",&T); while(T--) { int n,m; scanf("%d%d",&n,&m); build(1,0,n-1); while(m--) { char op[5]; scanf("%s",op); if(op[0]=='Q') { int l,r; scanf("%d%d",&l,&r); printf("%d\n",query(l,r,1,0,n-1)); } else { int p,v; scanf("%d%d",&p,&v); update(p,v,1,0,n-1); } } } return 0; }
HDU 3308 LCIS (端点更新+区间合并),布布扣,bubuko.com
标签:lcis hdu 3308 given n integers you have two operati hdu
原文地址:http://blog.csdn.net/darwin_/article/details/38706295