线段树(区间合并) HDOJ 3308 LCIS
题意:线段树操作: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的更多相关文章
- LCIS HDU - 3308 (线段树区间合并)
LCIS HDU - 3308 Given n integers. You have two operations: U A B: replace the Ath number by B. (inde ...
- HDU 3308 LCIS (线段树区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...
- hdu-3308 LCIS (线段树区间合并)
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu 3308(线段树区间合并)
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- HDU 3308 (线段树区间合并)
http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意: 两个操作 : 1 修改 单点 a 处的值. 2 求出 区间[a,b]内的最长上升子序列. 做法 ...
- HDU3308 线段树区间合并
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 ,简单的线段树区间合并. 线段树的区间合并:一般是要求求最长连续区间,在PushUp()函数中实 ...
- POJ 3667 Hotel(线段树 区间合并)
Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...
- HDU 3911 线段树区间合并、异或取反操作
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...
- HDU 3911 Black And White(线段树区间合并+lazy操作)
开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...
随机推荐
- WPF使用HierarchicalDataTemplate绑定Dictionary生成TreeView
Dictionary中的<string, CustomeType>CustomeType是一个集合,将其绑定生成一棵树,树的第一层节点是Dictionary的Key,第二层是Custome ...
- 每日五题(Spring)
1使用Spring框架的优点是什么? 控制反转: Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们. 面向切面的编程(AOP): Spring支持面向切面的编 ...
- hihocode #1388 : Periodic Signal NTT
#1388 : Periodic Signal 描述 Profess X is an expert in signal processing. He has a device which can ...
- 启用了不安全的HTTP方法解决办法 IBM APPSCAN
启用了不安全的HTTP方法解决办法 IBM APPSCAN 安全风险: 可能会在Web 服务器上上载.修改或删除Web 页面.脚本和文件. 可能原因: Web 服务器 ...
- SELECT INSTR(120,0000); 真
sql 排故 SELECT INSTR(120,0000); 真
- php网站前台utf-8格式有时会出现莫名其妙的空白行,重新保存下编码格式就可以了
php网站前台utf-8格式有时会出现莫名其妙的空白行,重新保存下编码格式就可以了.
- 怎么整合小图标,组合到一张png里面
1.将切出来的图片,一个个打开,用动工具组合到新的图片中: 2.将新建的图片,背景选为透明,保存为png格式: 3.通过css的background-position属性设置元素的背景图片.
- Scrapy爬虫报错:ModuleNotFoundError: No module named 'win32api'
运行 scrapy crawl douban_spider 出现报错: 解决办法:安装pywin32,下载适配安装的Python版本(64位,Python3.6) 下载地址: https://sour ...
- 可加装广告的swf播放器JS代码
加载flash动画前可以加载代码,设定广告显示秒数这些,还有些小bug,等有空了修复好法上来给大家 1. [代码][Java]代码<!DOCTYPE html PUBLIC "-/ ...
- html5--6-7 CSS选择器4
html5--6-7 CSS选择器4 实例 学习要点 掌握常用的CSS选择器 了解不太常用的CSS选择器 什么是选择器 当我们定义一条样式时候,这条样式会作用于网页当中的某些元素,所谓选择器就是样式作 ...