[hdu3308]线段树

题意:单点更新,区间LCIS(最长连续递增序列)查询。具备区间合并维护的性质,不用线段树用什么~

  1 #pragma comment(linker, "/STACK:10240000,10240000")
  2
  3 #include <iostream>
  4 #include <cstdio>
  5 #include <algorithm>
  6 #include <cstdlib>
  7 #include <cstring>
  8 #include <map>
  9 #include <queue>
 10 #include <deque>
 11 #include <cmath>
 12 #include <vector>
 13 #include <ctime>
 14 #include <cctype>
 15 #include <set>
 16
 17 using namespace std;
 18
 19 #define mem0(a) memset(a, 0, sizeof(a))
 20 #define lson l, m, rt << 1
 21 #define rson m + 1, r, rt << 1 | 1
 22 #define define_m int m = (l + r) >> 1
 23 #define Rep(a, b) for(int a = 0; a < b; a++)
 24 #define lowbit(x) ((x) & (-(x)))
 25 #define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
 26 #define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
 27 #define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
 28
 29 typedef double db;
 30 typedef long long LL;
 31 typedef pair<int, int> pii;
 32 typedef multiset<int> msi;
 33 typedef multiset<int>::iterator msii;
 34 typedef set<int> si;
 35 typedef set<int>::iterator sii;
 36 typedef vector<int> vi;
 37
 38 const int dx[8] = {1, 0, -1, 0, 1, 1, -1, -1};
 39 const int dy[8] = {0, -1, 0, 1, -1, 1, 1, -1};
 40 const int maxn = 1e5 + 7;
 41 const int maxm = 1e5 + 7;
 42 const int maxv = 1e7 + 7;
 43 const int MD = 1e9 +7;
 44 const int INF = 1e9 + 7;
 45 const double PI = acos(-1.0);
 46 const double eps = 1e-10;
 47
 48 int A[maxn];
 49
 50 struct SegTree {
 51     struct Node {
 52         int suflen, prelen, len;
 53     } tree[maxn << 2];
 54
 55     Node merge(Node a, Node b, int l, int m, int r) {
 56         Node c;
 57         int leftLen = m - l + 1, rightLen = r - m;
 58         c.prelen = a.prelen;
 59         if (c.prelen == leftLen && A[m] < A[m + 1]) c.prelen += b.prelen;
 60         c.suflen = b.suflen;
 61         if (c.suflen == rightLen && A[m] < A[m + 1]) c.suflen += a.suflen;
 62         c.len = a.len;
 63         c.len = max(c.len, b.len);
 64         if (A[m] < A[m + 1])c.len = max(c.len, a.suflen + b.prelen);
 65         return c;
 66     }
 67     void build(int l, int r, int rt) {
 68         if (l == r) {
 69             int x;
 70             scanf("%d", &x);
 71             A[l] = x;
 72             tree[rt].len = tree[rt].prelen =  tree[rt].suflen = 1;
 73             return ;
 74         }
 75         define_m;
 76         build(lson);
 77         build(rson);
 78         tree[rt] = merge(tree[rt << 1], tree[rt << 1 | 1], l, m, r);
 79     }
 80     void update(int p, int x, int l, int r, int rt) {
 81         if (l == r) {
 82             tree[rt].len = tree[rt].prelen =  tree[rt].suflen = 1;
 83             A[l] = x;
 84             return ;
 85         }
 86         define_m;
 87         if (p <= m) update(p, x, lson);
 88         else update(p, x, rson);
 89         tree[rt] = merge(tree[rt << 1], tree[rt << 1 | 1], l, m, r);
 90     }
 91     Node query(int L, int R, int l, int r, int rt) {
 92         if (L <= l && r <= R) return tree[rt];
 93         define_m;
 94         if (R <= m) return query(L, R, lson);
 95         if (L > m) return query(L, R, rson);
 96         return merge(query(L, m, lson), query(m + 1, R, rson), L, m, R);
 97     }
 98 };
 99
100 SegTree st;
101
102 int main() {
103     //freopen("in.txt", "r", stdin);
104     int T;
105     cin >> T;
106     while (T--) {
107         int n, m;
108         cin >> n >> m;
109         st.build(1, n, 1);
110         for (int i = 0, u, v; i < m; i++) {
111             char s[3];
112             scanf("%s%d%d", s, &u, &v);
113             if (s[0] == ‘U‘) {
114                 st.update(++u, v, 1, n, 1);
115             }
116             else {
117                 printf("%d\n", st.query(++u, ++v, 1, n, 1).len);
118             }
119         }
120     }
121     return 0;
122 }

时间: 2024-10-06 21:54:28

[hdu3308]线段树的相关文章

HDU3308 线段树区间合并

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 ,简单的线段树区间合并. 线段树的区间合并:一般是要求求最长连续区间,在PushUp()函数中实现区间合并操作. 解法: 由于对于一个区间的最长序列来说,最优解要么完全在左半序列,要么完全在右半序列,要么跨越中间点.所以可以构造线段树,维护结点区间的三个元素:最长上升前缀len[].l,最长上升后缀len[].r,最长上升序列len[].m.所以对于一个区间来说,有这样两种情况: 1. 左儿子

hdu3308 线段树 求最大连续递增序列

对每个节点   left表示该节点前缀最大连续上升 right为后缀最大连续上升 all为整个区间最大连续上升 pre为区间左边值   after为右边值 其他和别的线段树都差不多       关键是看如何合并 #include<stdio.h> #include<string.h> #include<iostream> using namespace std; #define LL(x) (x<<1) #define RR(x) ((x<<1)

hdu3308 线段树(区间合并)

给n个数字 U表示第A个数改为B.A是从0开始. Q输出最大的递增序列个数. 考虑左边,右边,和中间. #include<stdio.h> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define maxn 100010 int lsum[maxn<<2],rsum[maxn<<2],msum[maxn<<2]; int num[maxn]; int max(int x,int

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

Description Given n integers. You have two operations: U A B: replace the Ath number by B. (index counting from 0) Q A B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, b]. Input T in the first line, indicating the

HDU3308(LCIS) 线段树好题

题目链接:传送门 题目大意:给你n个数,m个操作.操作有两种:1.U x y 将数组第x位变为y   2. Q x y 问数组第x位到第y位连续最长子序列的长度.对于每次询问,输出一个答案 题目思路:线段树单点修改区间合并 这道题题目好在对pushup的理解,我们在向上更新的时候有注意情况的区分 1.如果左区间的最右边的值小于右区间最左边的值,则有一个待定答案是左儿子的右区间+右儿子的左区间 2.如果不符合第一个条件,则有一个待定答案是左区间最大值和右区间最大值中较大的那一个. 有一点要特别注意

线段树题目总结

一.单点更新 1.hdu1166 敌兵布阵:有N个兵营,每个兵营都给出了人数ai(下标从1开始),有四种命令,(1)"Addij",表示第i个营地增加j人.(2)"Sub i j",表示第i个营地减少j人.(3)"Query ij",查询第i个营地到第j个营地的总人数.(4)"End",表示命令结束.解题报告Here. 2.hdu1754 I Hate It:给你N个数,M个操作,操作分两类.(1)"QAB"

数据结构---线段树

线段树 转载请注明出处,谢谢!http://blog.csdn.net/metalseed/article/details/8039326  持续更新中···   一:线段树基本概念 1:概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN)! 性质:父亲的区间是[a,b],(c=(a+b)/2)左儿子的区间是[a,c],右儿子的区间是[c+1,b],线段树

(转载)线段树模板(来自胡浩大牛)

http://www.notonlysuccess.com/(今天看二叉树,想回来看看,发现大牛博客进不去...) 如果要学,就要好好学.我copy的,如有错,请看http://www.cnblogs.com/Mu-Tou/archive/2011/08/11/2134427.html [完全版]线段树 很早前写的那篇线段树专辑至今一直是本博客阅读点击量最大的一片文章,当时觉得挺自豪的,还去pku打广告,但是现在我自己都不太好意思去看那篇文章了,觉得当时的代码风格实在是太丑了,很多线段树的初学者

线段树总结 (转载 里面有扫描线类 还有NotOnlySuccess线段树大神的地址)

转载自:http://blog.csdn.net/shiqi_614/article/details/8228102 之前做了些线段树相关的题目,开学一段时间后,想着把它整理下,完成了大牛NotOnlySuccess的博文“完全版线段树”里的大部分题目,其博文地址Here,然后也加入了自己做过的一些题目.整理时,更新了之前的代码风格,不过旧的代码仍然保留着. 同样分成四类,不好归到前四类的都分到了其他.树状数组能做,线段树都能做(如果是内存限制例外),所以也有些树状数组的题目,会标示出来,并且放