您的位置:首页 > 其它

hdu 3308 LCIS(单点更新+区间合并)

2013-10-09 22:04 369 查看
题意:长度为N的数组,进行m次操作,

分为两种操作:

操作1:U A B 把位置A上的更新为B,

操作2: Q A B 输出[A,B]上的最长连续上升子序列

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308

思路:

操作1,:单点更新

操作2:求连续的上升子序列,区间合并,

线段树节点维护三个值,这个子序列的左边开始的个数,右边开始的个数,这个区间的子序列的个数

和poj 3368多了一点在于单点更新~~~

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define maxn 100010
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

int n,m;
int val[maxn];

struct segnode{
int lnum,rnum,num;
};
segnode tree[maxn<<2];

void PushUp(int rt,int l,int r){
int m = (l + r)/2;

tree[rt].lnum = tree[rt<<1].lnum;
tree[rt].rnum = tree[rt<<1|1].rnum;
tree[rt].num  = max(tree[rt<<1].num , tree[rt<<1|1].num);

if(val[m] < val[m+1]){
if(tree[rt<<1].lnum == (m - l + 1))
tree[rt].lnum += tree[rt<<1|1].lnum;

if(tree[rt<<1|1].rnum == (r - m))
tree[rt].rnum  += tree[rt<<1].rnum;

tree[rt].num = max(tree[rt].num,(tree[rt<<1].rnum + tree[rt<<1|1].lnum));
}
}

void build(int l,int r,int rt){
if(l == r){
tree[rt].lnum = 1;
tree[rt].rnum = 1;
tree[rt].num  = 1;
return ;
}
int m = (l + r)/2;
build(lson);
build(rson);
PushUp(rt,l,r);
}

void update(int pos,int c,int l,int r,int rt){
if(l == r){
val[pos] = c;
return ;
}
int m = (l + r)/2;
if(pos <= m) update(pos,c,lson);
else update(pos,c,rson);
PushUp(rt,l,r);
}

int query(int L,int R,int l,int r,int rt){
if(L <= l && r <= R){
return tree[rt].num;
}
int m = (l + r)/2;

if(R <= m) return query(L,R,lson);
else if(L > m) return query(L,R,rson);
else{
int lans = query(L,m,lson);
int rans = query(m+1,R,rson);
if(val[m] < val[m+1]){
int temp = min(tree[rt<<1].rnum ,(m - L + 1)) + min(tree[rt<<1|1].lnum , R - m);
return max(temp,max(lans,rans));
}
else{
return max(lans,rans);
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&val[i]);

build(1,n,1);
while(m--){
char op[10];
int a,b;
scanf("%s %d %d",op,&a,&b);
if(op[0]=='U'){
update(a+1,b,1,n,1);
}
else{
printf("%d\n",query(a+1,b+1,1,n,1));
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线段树 HDU