线段树(区间合并) 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 ]内最长连续黑色石头的 ...
随机推荐
- RecyclerView(替代ListView)使用方法介绍
在build.gradle文件加入以下代码 compile 'com.android.support:cardview-v7:21.0.3' compile 'com.android.support: ...
- gradle in action 笔记
原网址 https://lippiouyang.gitbooks.io/gradle-in-action-cn/content/
- Java对对象的引用 不是 引用调用 而是按值引用 Java不存在引用调用
call by reference Java call by value
- mysql优化-----多列索引的左前缀规则
索引优化策略 :索引类型 .1B-tree索引 关注的是:Btree索引的左前缀匹配规则,索引在排序和分组上发挥的作用. 注:名叫btree索引,大的方面看都用的二叉树.平衡树.但具体的实现上,各引擎 ...
- Hadoop 中的 (side data) 边数据
一.用途 边数据是作业所需的额外的只读数据,通常用来辅助主数据集: 二.方法 1.利用Configuration类来配置,利用setter()和getter()可方便的使用,方便存储一些基本的类型: ...
- POJ2243 Knight Moves —— A*算法
题目链接:http://poj.org/problem?id=2243 Knight Moves Time Limit: 1000MS Memory Limit: 65536K Total Sub ...
- HTML&CSS——background: url() no-repeat 0 -64px;CSS中背景图片定位方法
CSS中背景图片的定位,困扰我很久了.今天总算搞懂了,一定要记下来. 在CSS中,背景图片的定位方法有3种: 1)关键字:background-position: top left; 2)像素:bac ...
- c#-关于自动属性的思考
参考:c#-关于自动属性的思考 我的理解:自动属性跟 公有字段 一模一样,编程习惯而已.目前是这么认为的. 自动属性:public string Name{ get; set } 公有字段:pub ...
- codeforces 669E E. Little Artem and Time Machine(节点为map型的线段树)
题目链接: E. Little Artem and Time Machine time limit per test 2 seconds memory limit per test 256 megab ...
- POJ2689:Prime Distance(大数区间素数筛)
The branch of mathematics called number theory is about properties of numbers. One of the areas that ...