题目传送门

题意:线段树操作:1. 单点更新 2. 求区间的LCIS(longest consecutive increasing subsequence)

分析:注意是连续的子序列,就是简单的区间合并,记录线段的端点的值,如果rx[rt<<1] < lx[rt<<1|1]就区间合并,最后结果保存在ms中。因为记录的数据较多,索性结构体内再开一个结构体,感觉还不错。写完这题,对区间合并的操作有了更深的理解。

/************************************************
* Author :Running_Time
* Created Time :2015/9/25 星期五 10:37:34
* File Name :G.cpp
************************************************/ #include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-8;
struct ST {
struct Node {
int lx, rx;
int ls, rs, ms;
}node[N<<2];
void push_up(int l, int r, int rt) {
node[rt].ls = node[rt<<1].ls; node[rt].rs = node[rt<<1|1].rs;
node[rt].lx = node[rt<<1].lx; node[rt].rx = node[rt<<1|1].rx;
node[rt].ms = max (node[rt<<1].ms, node[rt<<1|1].ms);
int mid = (l + r) >> 1;
if (node[rt<<1].rx < node[rt<<1|1].lx) {
if (node[rt<<1].ls == mid - l + 1) {
node[rt].ls += node[rt<<1|1].ls;
}
if (node[rt<<1|1].rs == r - mid) {
node[rt].rs += node[rt<<1].rs;
}
node[rt].ms = max (node[rt].ms, node[rt<<1].rs + node[rt<<1|1].ls);
}
}
void build(int l, int r, int rt) {
if (l == r) {
scanf ("%d", &node[rt].lx);
node[rt].rx = node[rt].lx;
node[rt].ls = node[rt].rs = node[rt].ms = 1;
return ;
}
int mid = (l + r) >> 1;
build (lson); build (rson);
push_up (l, r, rt);
}
void updata(int p, int c, int l, int r, int rt) {
if (l == r) {
node[rt].lx = node[rt].rx = c; return ;
}
int mid = (l + r) >> 1;
if (p <= mid) updata (p, c, lson);
else updata (p, c, rson);
push_up (l, r, rt);
}
int query(int ql, int qr, int l, int r, int rt) {
if (ql <= l && r <= qr) {
return node[rt].ms;
}
int mid = (l + r) >> 1, ret = 0;
if (ql <= mid) {
ret = max (ret, query (ql, qr, lson));
}
if (qr > mid) {
ret = max (ret, query (ql, qr, rson));
}
if (node[rt<<1].rx < node[rt<<1|1].lx) {
ret = max (ret, min (mid - ql + 1, node[rt<<1].rs) + min (qr - mid, node[rt<<1|1].ls));
}
return ret;
}
}st; int main(void) {
int T; scanf ("%d", &T);
while (T--) {
int n, q; scanf ("%d%d", &n, &q);
st.build (1, n, 1);
for (int a, b, i=1; i<=q; ++i) {
char s[2]; scanf ("%s%d%d", &s, &a, &b);
if (s[0] == 'Q') {
printf ("%d\n", st.query (a + 1, b + 1, 1, n, 1));
}
else {
st.updata (a + 1, b, 1, n, 1);
}
}
} return 0;
}

新代码

#include <bits/stdc++.h>
using namespace std; typedef long long ll;
const int N = 1e5 + 5; #define lc o << 1
#define rc o << 1 | 1 int s[N<<2], sl[N<<2], sr[N<<2];
int al[N<<2], ar[N<<2];
int x[N]; void push_up(int o, int l, int r) {
sl[o] = sl[lc]; sr[o] = sr[rc];
al[o] = al[lc]; ar[o] = ar[rc];
s[o] = max(s[lc], s[rc]);
int mid = l + r >> 1;
if (ar[lc] < al[rc]) {
s[o] = max(s[o], sr[lc]+sl[rc]);
if (sl[o] == mid-l+1) sl[o] += sl[rc];
if (sr[o] == r-mid) sr[o] += sr[lc];
}
} void build(int o, int l, int r) {
if (l == r) {
al[o] = ar[o] = x[l];
s[o] = sl[o] = sr[o] = 1;
return ;
}
int mid = l + r >> 1;
build(lc, l, mid);
build(rc, mid+1, r);
push_up(o, l, r);
} void modify(int o, int l, int r, int p, int v) {
if (l == r) {
al[o] = ar[o] = v;
return ;
}
int mid = l + r >> 1;
if (p <= mid) modify(lc, l, mid, p, v);
else modify(rc, mid+1, r, p, v);
push_up(o, l, r);
} int query(int o, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) return s[o];
int mid = l + r >> 1, ret = 0;
if (ql <= mid) ret = max(ret, query(lc, l, mid, ql, qr));
if (qr > mid) ret = max(ret, query(rc, mid+1, r, ql, qr));
if (ql <= mid && qr > mid) {
if (ar[lc] < al[rc]) {
ret = max(ret, min(sr[lc], mid-ql+1)+min(sl[rc], qr-mid));
}
}
return ret;
} int main() {
int T;
scanf("%d", &T);
while (T--) {
int n, m;
scanf("%d%d", &n, &m);
for (int i=1; i<=n; ++i) {
scanf("%d", &x[i]);
}
build(1, 1, n);
char str[5];
int a, b;
while (m--) {
scanf("%s%d%d", &str, &a, &b);
if (str[0] == 'U') modify(1, 1, n, a+1, b);
else printf("%d\n", query(1, 1, n, a+1, b+1));
}
}
return 0;
}

  

线段树(区间合并) HDOJ 3308 LCIS的更多相关文章

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

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

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

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

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

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

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

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

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

    http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意: 两个操作  : 1 修改 单点  a 处的值. 2 求出 区间[a,b]内的最长上升子序列. 做法 ...

  6. HDU3308 线段树区间合并

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 ,简单的线段树区间合并. 线段树的区间合并:一般是要求求最长连续区间,在PushUp()函数中实 ...

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

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

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

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

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

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

随机推荐

  1. 安装NLTK

    在网上找了一圈,没找到几个靠谱的安装流程,在http://nltk.org/install.html上找到各平台下安装流程: Windows平台: 以下操作假定你的机器上还没有安装Python,如果你 ...

  2. ECMAScript学习笔记

    1. ECMAScript不存在块级作用域,因此在循环内部定义的变量,在循环外也是可以访问的 eg: var count =10; fpr(var i=0; i<count; i++){ ale ...

  3. 怎么显示隐藏Mac上的隐藏文件

    打开终端,输入:defaults write com.apple.finder AppleShowAllFiles -bool true 此命令显示隐藏文件defaults write com.app ...

  4. SDUT 3033 这题实在不知道起啥名好了(思维巧法)

    这题实在不知道起啥名好了 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 懒得想背景故事了,开门见山. 有一个长度为n的整数数列A ...

  5. jQuery制作信息提示弹出层插件【推荐】

    给大家分享一款非常实用的弹窗提示窗口插件,包含多种模式.带有回执函数值的功能.​1. [代码][JavaScript]代码 <script type="text/javascript& ...

  6. 基于C#实现Windows服务状态启动和停止服务的方法

    网址:http://www.jb51.net/article/89230.htm

  7. jsch文件下载功能

    转载:http://www.cnblogs.com/longyg/archive/2012/06/25/2561332.html 上一篇讲述了使用JSch实现文件上传的功能,这一篇主要讲述一下JSch ...

  8. 单片机知识是Linux驱动开发的基础之一

    这是arm裸机1期加强版第1课第2节课程的wiki文字版. 为什么没前途也要学习单片机? 因为它是个很好的入口. 学习单片机可以让我们抛开复杂的软件结构,先掌握硬件操作,如:看原理图.芯片手册.写程序 ...

  9. 相对定位relative与绝对定位absolute

    relative:相对定位,并没有脱离原来文档流,依然在原来的位置上,可以通过设置left,top,来设置自己的偏移量,但是它依然占据自己原来的位置,偏移的位置会遮盖其他的元素 absolute:绝对 ...

  10. js 排列 组合

    <script> //组合 function C(arr, num){ var r=[]; (function f(t,a,n){ if (n==0) return r.push(t); ...