hdu3308--LCIS 最大连续递增序列长度

这个是动态的,所以要用线段树维护。代码里有注释因为ls敲成lsum,rs敲成rsum查错查了好久。。

  1 #include <set>
  2 #include <map>
  3 #include <cmath>
  4 #include <ctime>
  5 #include <queue>
  6 #include <stack>
  7 #include <cctype>
  8 #include <cstdio>
  9 #include <string>
 10 #include <vector>
 11 #include <cstdlib>
 12 #include <cstring>
 13 #include <iostream>
 14 #include <algorithm>
 15 using namespace std;
 16 typedef unsigned long long ull;
 17 typedef long long ll;
 18 const int inf = 0x3f3f3f3f;
 19 const double eps = 1e-8;
 20 template <class T>
 21 inline bool scan_d(T &ret)
 22 {
 23     char c;
 24     int sgn;
 25     if(c=getchar(),c==EOF) return 0;
 26     while(c!=‘-‘&&(c<‘0‘||c>‘9‘))
 27         c=getchar();
 28     sgn=(c==‘-‘)?-1:1;
 29     ret=(c==‘-‘)?0:(c-‘0‘);
 30     while(c=getchar(),c>=‘0‘&&c<=‘9‘)
 31         ret=ret*10+(c-‘0‘);
 32     ret*=sgn;
 33     return 1;
 34 }
 35
 36 const int maxn = 1e5+10;
 37 int ls[maxn<<2],rs[maxn<<2];       //ls为区间左值,rs为区间右值  比较时要用到。
 38 int lsum[maxn<<2],rsum[maxn<<2],sum[maxn<<2];  //lsum为区间左上升长度,rsum为区间右上升长度,sum为区间最大上升长度。
 39
 40 void push_up(int l,int r,int pos)
 41 {
 42     ls[pos] = ls[pos<<1];
 43     rs[pos] = rs[pos<<1|1];
 44     lsum[pos] = lsum[pos<<1];
 45     rsum[pos] = rsum[pos<<1|1];
 46     sum[pos] = max(sum[pos<<1],sum[pos<<1|1]);
 47     int mid = (l + r) >> 1;
 48     if (ls[pos<<1|1] > rs[pos<<1])
 49     {
 50         sum[pos] = max(sum[pos],rsum[pos<<1] + lsum[pos<<1|1]);
 51         if (lsum[pos<<1] == mid - l + 1)               //左区间左上升长度已满
 52             lsum[pos] += lsum[pos<<1|1];
 53         if (rsum[pos<<1|1] == r - mid)                 //同理,
 54             rsum[pos] += rsum[pos<<1];
 55     }
 56 }
 57
 58 void build (int l,int r,int pos)
 59 {
 60     if (l == r)
 61     {
 62         int tmp;
 63         scanf ("%d",&tmp);
 64         ls[pos] = tmp;
 65         rs[pos] = tmp;
 66         lsum[pos] = rsum[pos] = sum[pos] = 1;
 67         return;
 68     }
 69     int mid =(l + r) >> 1;
 70     build(l,mid,pos<<1);
 71     build(mid+1,r,pos<<1|1);
 72     push_up(l,r,pos);
 73 }
 74
 75 void update(int l,int r,int pos,int x,int val)
 76 {
 77     if (l == r)
 78     {
 79         ls[pos] = rs[pos] = val;
 80         return;
 81     }
 82     int mid = (l + r) >> 1;
 83     if (x <= mid)
 84         update(l,mid,pos<<1,x,val);
 85     else
 86         update(mid+1,r,pos<<1|1,x,val);
 87     push_up(l,r,pos);
 88 }
 89
 90
 91 int query(int l,int r,int pos,int ua,int ub)
 92 {
 93     if (ua <= l && ub >= r)
 94     {
 95         return sum[pos];
 96     }
 97     int mid = (l + r) >> 1;
 98     int ans1 = 0,ans2 = 0,ans3 = 0;
 99     if (ua <= mid)
100         ans1 = query(l,mid,pos<<1,ua,ub);
101     if (ub > mid)
102         ans2 = query(mid+1,r,pos<<1|1,ua,ub);
103     if (ls[pos<<1|1] > rs[pos<<1])
104         ans3 = min(lsum[pos<<1|1],ub-mid) + min(rsum[pos<<1],mid-ua+1);
105     return max(ans1,max(ans2,ans3));
106 }
107
108
109 int main(void)
110 {
111     #ifndef ONLINE_JUDGE
112     freopen("in.txt","r",stdin);
113     #endif
114     int t;
115     cin>>t;
116     while (t--)
117     {
118         int n,q;
119         scanf ("%d%d",&n,&q);
120         build(1,n,1);
121         char op[10];
122         int x,y;
123         for (int i = 0; i < q; i++)
124         {
125             scanf ("%s%d%d",op,&x,&y);
126             if (op[0] == ‘Q‘)
127                 printf("%d\n",query(1,n,1,x+1,y+1));
128             if (op[0] == ‘U‘)
129                 update(1,n,1,x+1,y);
130         }
131     }
132     return 0;
133 }
时间: 2024-10-21 18:01:12

hdu3308--LCIS 最大连续递增序列长度的相关文章

得到最长连续递增序列

今天作死,看到别人发出来的笔试题就开干了,这tmd还理解错题目了,连续递增序列理解成上一个=下一个-1了. 这是我的成果,撸了4个多小时的: public class Test12 { public static void main(String[] args){ /** * 需求:找出最长的连续递增序列 * 步骤: * 1.找出所有连续序列可能结果,删除不是连续递增序列的,加入集合 * 2.集合排序,取第一个 * * 方式2: * 0.默认len为数组长度 * 1.找出数组中长度为len的序列

LeetCode 674. 最长连续递增序列(Longest Continuous Increasing Subsequence) 18

674. 最长连续递增序列 674. Longest Continuous Increasing Subsequence 题目描述 给定一个未经排序的整型数组,找到最长且连续的递增序列. Given an unsorted array of integers, find the length of longest continuous increasing subsequence (subarray). 每日一算法2019/5/21Day 18LeetCode674. Longest Conti

LeetCode 674. Longest Continuous Increasing Subsequence最长连续递增序列 (C++/Java)

题目: Given an unsorted array of integers, find the length of longest continuous increasing subsequence (subarray). Example 1: Input: [1,3,5,4,7] Output: 3 Explanation: The longest continuous increasing subsequence is [1,3,5], its length is 3. Even tho

LeetCode - 最长连续递增序列

题目描述: 给定一个未经排序的整数数组,找到最长且连续的的递增序列. 示例 1: 输入: [1,3,5,4,7] 输出: 3 解释: 最长连续递增序列是 [1,3,5], 长度为3.尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为5和7在原数组里被4隔开. 示例 2: 输入: [2,2,2,2,2] 输出: 1 解释: 最长连续递增序列是 [2], 长度为1. code: public class Solution { public int findLengthOfLCIS(i

hdu 3308 线段树,单点更新 求最长连续上升序列长度

LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 9713    Accepted Submission(s): 4215 Problem Description Given n integers.You have two operations:U A B: replace the Ath number by B. (index

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)

[LeetCode] Longest Continuous Increasing Subsequence 最长连续递增序列

Given an unsorted array of integers, find the length of longest continuous increasing subsequence. Example 1: Input: [1,3,5,4,7] Output: 3 Explanation: The longest continuous increasing subsequence is [1,3,5], its length is 3. Even though [1,3,5,7] i

最长递增子序列(输出最长递增序列 及其长度)

最长递增子序列的解法有很多种,常用的有最长公共子序列法.动态规划.记录所有递增序列长度最大值的方法. 最长公共子序列法:如例子中的数组A{5,6, 7, 1, 2, 8},则我们排序该数组得到数组A‘{1, 2, 5, 6, 7, 8},然后找出数组A和A’的最长公共子序列即可.显然这里最长公共子序列为{5, 6, 7, 8},也就是原数组A最长递增子序列. 在http://blog.csdn.net/yysdsyl/article/details/4226630中有详细解释. 动态规划:参见h

hdu3308—LCIS

题目链接 http://hdu.hustoj.com/showproblem.php?pid=3308 问题描述 给出n个整数,有两种操作 1)U A B:用B取代第A个数(下标从0开始) 2)Q A B:输出在[A,B]中最长连续递增子序列的长度分析 给出一个序列,两种操作,分别是单点更新值和查询区间的最长连续递增子序列长 度,典型的线段树问题 首先考虑线段树的节点需要记录哪些值: 1)包含左端点的最长连续递增子序列长度,记作pre[] 2)包含右端点的最长连续递增子序列长度,记作suf[]