hdu-3308-LCIS 线段树
2014-02-17 19:31
288 查看
结构里
a 该段最左的数
b该段最有的数
la该段从左开始 向右的最长递增长度
lb该段从右开始 向左的最长递增长度
ll该段的 最长递增长度
len该段的总长度
l 该段左端点
r 该段右端点
然后画图思考下,怎么递归着建树和更新,求区间最大值。。。
a 该段最左的数
b该段最有的数
la该段从左开始 向右的最长递增长度
lb该段从右开始 向左的最长递增长度
ll该段的 最长递增长度
len该段的总长度
l 该段左端点
r 该段右端点
然后画图思考下,怎么递归着建树和更新,求区间最大值。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define N 101000 struct node{ int a,b; int la,lb,ll; int len; int l,r; }tree[3*N]; int p ; void build(int id,int x,int y) { tree[id].l=x; tree[id].r=y; tree[id].a=p[x]; tree[id].b=p[y]; tree[id].len=y-x+1; int t1=id<<1,t2=(id<<1)+1; if(x==y) { tree[id].la=1; tree[id].lb=1; tree[id].ll=1; return ; } int mid=(x+y)>>1; build(t1,x,mid); build(t2,mid+1,y); if(tree[t1].len == tree[t1].la && tree[t1].b<tree[t2].a) tree[id].la=tree[t1].la+tree[t2].la; else tree[id].la=tree[t1].la; if(tree[t2].len==tree[t2].lb && tree[t1].b<tree[t2].a) tree[id].lb=tree[t2].lb+tree[t1].lb; else tree[id].lb=tree[t2].lb; tree[id].ll=max(tree[t1].ll,tree[t2].ll); if(tree[t1].b<tree[t2].a) tree[id].ll=max(tree[id].ll,tree[t1].lb+tree[t2].la); } int query(int id,int x,int y) { int left=tree[id].l; int right=tree[id].r; int mid=(left+right)>>1; if(x==left && y==right) return tree[id].ll; if(y<=mid) return query(id<<1,x,y); else if(x>=mid+1) return query((id<<1)+1,x,y); else { int t1=query(id<<1,x,mid); int t2=query((id<<1)+1,mid+1,y); if(tree[id<<1].b < tree[(id<<1)+1].a) return max(max(t1,t2),min(tree[id<<1].lb,mid-x+1)+min(tree[(id<<1)+1].la,y-mid)); else return max(t1,t2); } } void change(int id,int x,int y) { int left=tree[id].l; int right=tree[id].r; int mid=(left+right)>>1; if(left==right && left==x) { tree[id].a=y; tree[id].b=y; return ; } int t1=id<<1,t2=(id<<1)+1; if(x<=mid) change(id<<1,x,y); else change((id<<1)+1,x,y); if(x==left) tree[id].a=y; else if(x==right) tree[id].b=y; if(tree[t1].len == tree[t1].la && tree[t1].b<tree[t2].a) tree[id].la=tree[t1].la+tree[t2].la; else tree[id].la=tree[t1].la; if(tree[t2].len==tree[t2].lb && tree[t1].b<tree[t2].a) tree[id].lb=tree[t2].lb+tree[t1].lb; else tree[id].lb=tree[t2].lb; tree[id].ll=max(tree[t1].ll,tree[t2].ll); if(tree[t1].b<tree[t2].a) tree[id].ll=max(tree[id].ll,tree[t1].lb+tree[t2].la); } int main() { int t; scanf("%d",&t); while(t--) { int n,m,i,j,k; scanf("%d%d",&n,&k); for(i=1;i<=n;i++) scanf("%d",&p[i]); build(1,1,n); char ch[2]; int h,g; while(k--) { scanf("%s",ch); if(ch[0]=='Q'){ scanf("%d%d",&g,&h); g++; h++; int ans=query(1,g,h); printf("%d\n",ans); } else if(ch[0]=='U'){ scanf("%d%d",&g,&h); g++; change(1,g,h); } } } }
相关文章推荐
- HDU 1166 敌兵布阵
- HDU 1166 敌兵布阵
- 一个 fork 的面试题
- db2错误码整理
- 【几何+暴力】-CF-391D1-Supercollider
- powerpc开发板使用收获总结
- Sicily 1926
- UILabel
- J2EE——Jsp的学习
- js中call与apply用法
- Balanced Binary Tree
- 设计一个可以用<<和逗号输入矩阵的方案
- [Python]python学习笔记(一)——语法
- 【转】PHP怎么实现字符串翻转(包含中文汉字)
- 模视图转换
- Sicily 1930
- openwrt启动脚本分析
- Install Shield 脚本(总)
- 好玩的指针
- 用LaTeX制作个人简历