题目传送门

题意:线段树操作: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. 使用JWT设计SpringBoot项目api接口安全服务

    转载直: 使用JWT设计SpringBoot项目api接口安全服务

  2. iOS app url scheme跳转到淘宝商品详情页 唤醒app

    最近涉及的一个业务,在app内的一个广告,点击打开webView,加载的是一个淘宝商品详情页,效果是打开该webView自动跳转至淘宝对应的页面,同时在自己的app仍然加载页面,点击评论等也同样能跳转 ...

  3. XJTUOJ wmq的A×B Problem FFT/NTT

    wmq的A×B Problem 发布时间: 2017年4月9日 17:06   最后更新: 2017年4月9日 17:07   时间限制: 3000ms   内存限制: 512M 描述 这是一个非常简 ...

  4. java中方法中声明三个点“...”作用

    public class Test {  public static void main(String[] args) {   String str[] = {"s"," ...

  5. MapReduce算法形式一:WordCount

    MapReduce算法形式一:WordCount 这种形式可以做一些网站登陆次数,或者某个电商网站的商品销量啊诸如此类的,主要就是求和,但是求和之前还是要好好清洗数据的,以免数据缺省值太多,影响真实性 ...

  6. bash shell parameter expansion

    1 ${parameter%word}和${parameter%%word} ${parameter%word},word是一个模式,从parameter这个参数的末尾往前开始匹配.单个%进行最短匹配 ...

  7. linux下使用无线网卡的命令行方法(wifi,iwconfig)

    原文地址:linux下使用无线网卡的命令行方法(wifi,iwconfig) 作者:andyhzw (1)首先关闭开发板的有线网卡 [root@FriendlyARM /]# ifconfig eth ...

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

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

  9. 一步一步学Silverlight 2系列(12):数据与通信之WebClient

    概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  10. Apache Maven的下载、安装、测试

    Apache Maven是个软件项目管理工具,基于项目对象模型(Project Object Model,POM)的概念,Maven可用来管理项目的依赖.编译.文档等信息. 使用Maven管理项目时, ...