(线段树)hdoj 3308-LCIS

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,ba,b.

InputT in the first line, indicating the case number. 
Each case starts with two integers n , m(0<n,m<=10 5). 
The next line has n integers(0<=val<=10 5). 
The next m lines each has an operation: 
U A B(0<=A,n , 0<=B=10 5
OR 
Q A B(0<=A<=B< n). 
OutputFor each Q, output the answer.Sample Input

1
10 10
7 7 3 3 5 9 9 8 1 8
Q 6 6
U 3 4
Q 0 1
Q 0 5
Q 4 7
Q 3 5
Q 0 2
Q 4 6
U 6 10
Q 0 9

Sample Output

1
1
4
2
3
1
2
5
  1 #include <iostream>
  2 //#include<bits/stdc++.h>
  3 #include <stack>
  4 #include <queue>
  5 #include <map>
  6 #include <set>
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <math.h>
 11 using namespace std;
 12 typedef long long ll;
 13 typedef unsigned long long ull;
 14 const int MAX=1e5+5;
 15 struct node
 16 {
 17     int left,right,mid;
 18     int x,y;
 19 }st[10*MAX];
 20 void pushup(int l,int r,int k)
 21 {
 22     st[k].left=st[2*k].left;
 23     st[k].right=st[2*k+1].right;
 24     st[k].mid=max(st[2*k].mid,st[2*k+1].mid);
 25     st[k].x=st[2*k].x;
 26     st[k].y=st[2*k+1].y;
 27     if(st[2*k].y<st[2*k+1].x)
 28     {
 29         st[k].mid=max(st[k].mid,st[2*k].right+st[2*k+1].left);
 30         if(st[2*k].left==(l+r)/2-l)
 31             st[k].left=st[2*k].left+st[2*k+1].left;
 32         if(st[2*k+1].right==r-(l+r)/2)
 33             st[k].right=st[2*k+1].right+st[2*k].right;
 34     }
 35 }
 36 void init(int l,int r,int k)
 37 {
 38     st[k].left=st[k].right=st[k].mid=r-l;
 39     if(l+1==r)
 40     {
 41         scanf("%d",&st[k].x);
 42         st[k].y=st[k].x;
 43         return;
 44     }
 45     init(l,(l+r)/2,2*k);
 46     init((l+r)/2,r,2*k+1);
 47     pushup(l,r,k);
 48 }
 49 void update(int l,int r,int ul,int ur,int val,int k)//当下[l,r), 目标更新[ul,ur) 为val
 50 {
 51     if(ul==l&&ur==r)
 52     {
 53         st[k].x=st[k].y=val;
 54         return;
 55     }
 56     int mid=(l+r)/2;
 57     if(mid>=ur)
 58         update(l,mid,ul,ur,val,2*k);
 59     if(mid<=ul)
 60         update(mid,r,ul,ur,val,2*k+1);
 61     st[k].mid=max(st[2*k].mid,st[2*k+1].mid);
 62     st[k].left=st[2*k].left;
 63     st[k].right=st[2*k+1].right;
 64     st[k].x=st[2*k].x;
 65     st[k].y=st[2*k+1].y;
 66     if(st[2*k].y<st[2*k+1].x)
 67     {
 68         st[k].mid=max(st[k].mid,st[2*k].right+st[2*k+1].left);
 69     if(st[2*k].left==(l+r)/2-l)
 70         st[k].left+=st[2*k+1].left;
 71     if(st[2*k+1].right==r-(l+r)/2)
 72         st[k].right+=st[2*k].right;
 73     }
 74     return;
 75 }
 76 int query(int l,int r,int ql,int qr,int k)
 77 {
 78     if(l>=ql&&r<=qr)
 79         return st[k].mid;
 80     int mid=(l+r)/2;
 81     if(mid<=ql)
 82         return query(mid,r,ql,qr,2*k+1);
 83     else if(mid>=qr)
 84         return query(l,mid,ql,qr,2*k);
 85     else
 86     {
 87         int an;
 88         an=max(query(l,mid,ql,qr,2*k),query(mid,r,ql,qr,2*k+1));
 89         if(st[2*k].y<st[2*k+1].x)
 90             an=max(an,min(st[2*k].right,mid-ql)+min(st[2*k+1].left,qr-mid));
 91         return an;
 92     }
 93 }
 94 int t;
 95 int N,M;
 96 char op[10];
 97 int qq,pp;
 98 int main()
 99 {
100     scanf("%d",&t);
101     while(t--)
102     {
103         scanf("%d %d",&N,&M);
104         init(1,N+1,1);
105         for(int i=1;i<=M;i++)
106         {
107             scanf("%s %d %d",op,&qq,&pp);
108             qq++;
109             if(op[0]==‘U‘)
110             {
111                 update(1,N+1,qq,qq+1,pp,1);
112             }
113             else
114             {
115                 pp++;
116                 printf("%d\n",query(1,N+1,qq,pp+1,1));
117             }
118         }
119     }
120 }
时间: 2024-10-06 15:50:55

(线段树)hdoj 3308-LCIS的相关文章

线段树 [HDU 3308] LCIS

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

树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)

题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一个节点在路径上) 3 u v:查询u到v路径上有多少个黑色边 思路: 对树进行树链剖分,分成重链和轻链,用两棵线段树W,L来维护.W维护树上在重链上的u和v之间的边的翻转情况(操作在线段树上的[pos[v],pos[u]]区间):L维护树上在重链上的u和v之间的相邻边的翻转情况.那么某一个点u与它父

线段树 HDU 3308

t 题目大意:给你n个数,m个操作.操作有两种:1.U x y 将数组第x位变为y   2. Q x y 问数组第x位到第y位连续最长子序列的长度.对于每次询问,输出一个答案 #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define MAXN 100010 struct node { int l,r,ls,rs,ms;//维护从左边开始 最大 到右边结束 3

HDU 3308 LCIS (端点更新+区间合并)

刚刚做了两道LCIS,碰到这道线段树,脑抽了似的写 线段树+dp(LCIS),贡献一发TLE. 才想到要区间合并,query函数写了好久.下面有详细注释,参见代码吧~~欢迎点赞,欢迎卖萌~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 #include<cstdio> #inc

HDU 3308 LCIS(线段树)

Problem 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

HDU 3308 LCIS 线段树 区间更新

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目描述: 有两种操作, U x y  , 第xth赋值为y .Q x y , 查询区间x-y的最长连续上升子序列的长度L 解题思路: 对于线段树不好的我依然好难.....有太多细节需要注意了....但是这是一道很好的题, 一段区间的L可能从三个地方来, 一种是中间, 一种是以左起点为开头的, 一种是以右起点结尾的, 这样查询的时候就要注意了: 如果两段的中间值是a[m] < a[m+1]

HDU 3308 LCIS (线段树区间合并)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[mid + 1] > a[mid],写的细心点就好了. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int MAXN = 1

hdu 3308 LCIS(线段树)

pid=3308" target="_blank" style="">题目链接:hdu 3308 LCIS 题目大意:给定一个序列,两种操作: Q l r:查询区间l,r中的最长连续递增序列长度 U p x:将位置p上的数改成x 解题思路:线段树上的区间合并,这是在左右子树合并的时候要推断一下是否满足递增就可以. #include <cstdio> #include <cstring> #include <algorit

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5792    Accepted Submission(s): 2513 Problem Description Given n integers. You have two

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

题目传送:LCIS 线段树,区间合并,一次过啦,没有纠结,这几天过的最愉快的一个题 思路:求最长连续上升子序列,外带单点更新,经典的线段树题目.具体看代码注释 AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include <stack>