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

题意:给定n个数,两个操作:

U A B:将位置A的数值改成B

Q A B:查询[A,B]内最长连续上升子序列的长度。

注意到‘连续’一词,可以用线段树维护[L,R]区间内的LICS。

定义结构Node,内部l,r为左右儿子的下标。ls,rs记录当前区间分别从左起和右起的LICS长度,s记录整个区间内的LICS长度。

pushup:和一般的区间合并操作一样,但是要注意假如合并的左右子树中间有可能成为LICS的时候,要判断是否符合条件,即左起右边界和右起左边界是否满足严格的关系。

update:更新节点的时候直接赋值,再更新到线段树上的操作也是很常规的。

query:比较奇特,因为有左起右边界和右起左边界连接起来的情况,所以查询的时候不是缩小线段树规模,而是缩小查询规模来获得解。而且要注意[L,R]的边界问题。子树的范围未必恰好满足,可能会更长。

 #include <bits/stdc++.h>
using namespace std; #define lrt rt << 1
#define rrt rt << 1 | 1
typedef struct Node {
int l, r;
int ls, s, rs;
}Node;
const int maxn = ;
char cmd[];
int n, q;
int x[maxn];
Node seg[maxn<<]; void pushUP(int rt, int len) {
seg[rt].ls = seg[lrt].ls; seg[rt].rs = seg[rrt].rs;
if(seg[rt].ls == len-len/) {
if(x[seg[lrt].r] < x[seg[rrt].l]) {
seg[rt].ls += seg[rrt].ls;
}
}
if(seg[rt].rs == len/) {
if(x[seg[lrt].r] < x[seg[rrt].l]) {
seg[rt].rs += seg[lrt].rs;
}
}
seg[rt].s = max(seg[lrt].s, seg[rrt].s);
if(x[seg[lrt].r] < x[seg[rrt].l]) {
seg[rt].s = max(seg[rt].s, seg[lrt].rs+seg[rrt].ls);
}
} void build(int l, int r, int rt) {
seg[rt].l = l; seg[rt].r = r;
if(l == r) {
seg[rt].ls = seg[rt].rs = seg[rt].s = ;
return;
}
int mid = (l + r) >> ;
build(l, mid, lrt);
build(mid+, r, rrt);
pushUP(rt, r-l+);
} void update(int L, int R, int rt) {
if(L <= seg[rt].l && seg[rt].r <= R) {
seg[rt].ls = seg[rt].rs = seg[rt].s = ;
return;
}
int mid = (seg[rt].l + seg[rt].r) >> ;
if(L <= mid) update(L, R, lrt);
if(mid < R) update(L, R, rrt);
pushUP(rt, seg[rt].r-seg[rt].l+);
} int query(int L, int R, int rt) {
if(L == seg[rt].l && R == seg[rt].r) return seg[rt].s;
int mid = (seg[rt].l + seg[rt].r) >> ;
if(mid >= R) return query(L, R, lrt);
else if(mid + <= L) return query(L, R, rrt);
else {
int tmp = max(query(L, mid, lrt), query(mid+, R, rrt));
if(x[seg[lrt].r] < x[seg[rrt].l]) {
tmp = max(tmp, min(seg[lrt].rs, mid-L+)+min(seg[rrt].ls, R-mid));
}
return tmp;
}
} int main() {
// freopen("in", "r", stdin);
int T, a, b;
scanf("%d", &T);
while(T--) {
scanf("%d %d", &n, &q);
for(int i = ; i <= n; i++) {
scanf("%d", &x[i]);
}
build(, n, );
while(q--) {
scanf("%s %d %d", cmd, &a, &b);
a++;
if(cmd[] == 'U') {
x[a] = b;
update(a, a, );
}
else {
b++;
printf("%d\n", query(a, b, ));
}
}
}
return ;
}

[HDOJ3308]LCIS(线段树,区间合并)的更多相关文章

  1. hdu-3308 LCIS (线段树区间合并)

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  2. HDU 3308 LCIS (线段树区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...

  3. hud 3308 LCIS 线段树 区间合并

    题意: Q a b 查询[a, b]区间的最长连续递增子序列的长度 U a b 将下表为a的元素更新为b 区间合并一般都有3个数组:区间最值,左区间最值和右区间最值 具体详见代码 #include & ...

  4. LCIS HDU - 3308 (线段树区间合并)

    LCIS HDU - 3308 Given n integers. You have two operations: U A B: replace the Ath number by B. (inde ...

  5. hdu 3308(线段树区间合并)

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  6. POJ 3667 Hotel(线段树 区间合并)

    Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...

  7. HDU 3911 线段树区间合并、异或取反操作

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...

  8. HDU 3911 Black And White(线段树区间合并+lazy操作)

    开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...

  9. HYSBZ 1858 线段树 区间合并

    //Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...

  10. poj3667 线段树 区间合并

    //Accepted 3728 KB 1079 ms //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...

随机推荐

  1. html里那些细节

    target="_top",项目是frameset形式写的,用这个在跳转的时候从父框架跳转

  2. oracle中dual表的使用

    dual表是一个虚拟表,用来和select语句一起使用.1.查看当前用户select  user from dual2.用来调用系统函数select to_char(sysdate,'yyyy-mm- ...

  3. JavaSPI机制学习笔记

    最近在阅读框架源代码时,常常看到 SPI 的子包, 忍不住查了下: Service Provider Interface : 服务提供接口. JavaSPI 实际上是“基于接口的编程+策略模式+配置文 ...

  4. java多线程中的生产者与消费者之等待唤醒机制@Version2.0

    二.生产者消费者模式的学生类成员变量生产与消费demo, @Version2.0 在学生类中添加同步方法:synchronized get()消费者,synchronized set()生产者 最终版 ...

  5. java笔试题整理

    exit()是system类的方法,如system.exit(); 如果某个方法是静态的,它的行为就不具有多态性. 类后面没有括号,方法必须要有返回值.如果没有返回值,要写void 构造函数不具有多态 ...

  6. visio 由于形状保护和/或图层属性设置不能进行编辑

    方式一.菜单栏 --> 格式 --> 保护 方式二.用鼠标右键单击组件, 格式 --> 保护 . 转自:http://blog.163.com/chen_dawn/blog/stat ...

  7. POJ 2192 :Zipper(DP)

    http://poj.org/problem?id=2192 Zipper Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1 ...

  8. [HTML]POST方法和GET方法

    GET方法: function btn_get_click(){ var httpRequest = new XMLHttpRequest(); httpRequest.onreadystatecha ...

  9. sass初步认识2

    sass可以使用变量,采用 $ 来进行变量声明,格式为: $highlight-color:#f90;(声明方式和css属性声明类似.使用的变量名可以更加语义化) 与js分为全局变量和局部变量类似,s ...

  10. 杭电1097-A hard puzzle

    Problem Description lcy gives a hard puzzle to feng5166,lwg,JGShining and Ignatius: gave a and b,how ...