LCIS
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3056 Accepted Submission(s): 1342
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].
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 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).
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).
Output
For 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
Author
shǎ崽
Source
Recommend
wxl
借用某大神的讲解:
PushUp函数和query函数是关键 ,PushUp函数向上更新时,先将lsum[rt]用
lsum[rt<<1]也就是左子区间左边开始的最大长度,如果这个区间长度刚好是l到mid之间的长度,说明区间已经穿过中点了,应该
在加上右子区间lsum[rt<<1|1]这部分,类似的可以更新rsum[rt]。对于sum[rt]应该对应rsum[rt<<1]+lsum[rt<<1|1],
sum[rt<<1],sum[rt<<1|1]三种情况中的最大值,因为满足条件的最长单调区间可以是左半部分,右半部分,或者贯穿中点。
理解了这部分那么query函数可以按照类似的思路来写,但要注意的是对于贯穿中点的判断条件是A[mid]<A[mid+1],这样才能
将两部分加起来。
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <map>
#include <string>
#include <stack>
#include <cctype>
#include <vector>
#include <queue>
#include <set>
#include <utility>
using namespace std;
//#define Online_Judge
#define outstars cout << "***********************" << endl;
#define clr(a,b) memset(a,b,sizeof(a))
#define lson l , mid , rt << 1
#define rson mid + 1 , r , rt << 1 | 1
#define mk make_pair
#define FOR(i , x , n) for(int i = (x) ; i < (n) ; i++)
#define FORR(i , x , n) for(int i = (x) ; i <= (n) ; i++)
#define REP(i , x , n) for(int i = (x) ; i > (n) ; i--)
#define REPP(i ,x , n) for(int i = (x) ; i >= (n) ; i--)
const int MAXN = 100000 + 500;
const long long LLMAX = 0x7fffffffffffffffLL;
const long long LLMIN = 0x8000000000000000LL;
const int INF = 0x7fffffff;
const int IMIN = 0x80000000;
#define eps 1e-8
#define mod 1000000007
typedef long long LL;
const double PI = acos(-1.0);
typedef double D;
typedef pair<int , int> pi;
///#pragma comment(linker, "/STACK:102400000,102400000")
int A[MAXN] , sum[MAXN << 2] , lsum[MAXN << 2] , rsum[MAXN << 2] , n , T , m , a , b;
void pushup(int rt , int len , int mid)
{
lsum[rt] = lsum[rt << 1];
rsum[rt] = rsum[rt << 1 | 1];
int t = 1;
if(A[mid] < A[mid + 1])
{
if(lsum[rt] == len - (len >> 1))
{
lsum[rt] += lsum[rt << 1 | 1];
}
if(rsum[rt] == len >> 1)
{
rsum[rt] += rsum[rt << 1];
}
t = lsum[rt << 1| 1] + rsum[rt << 1];
}
sum[rt] = max(t , max(sum[rt << 1] , sum[rt << 1 | 1]));
}
void build(int l , int r , int rt)
{
if(l == r)
{
sum[rt] = lsum[rt] = rsum[rt] = 1;
return ;
}
int mid = (l + r) >> 1;
build(lson);build(rson);
pushup(rt , r - l + 1 , mid);
}
void update(int p , int l , int r, int rt)
{
if(l == r)return ;
int mid = (l + r) >> 1;
if(p <= mid)update(p , lson);
else update(p , rson);
pushup(rt , r - l + 1 , mid);
}
int query(int L , int R , int l , int r ,int rt)
{
if(L <= l&& r <= R)return sum[rt];
int mid = (l + r) >> 1;
if(l == r)return 1;
int ans = 0;
if(R <= mid)ans = max(ans , query(L , R , lson));
else if (L > mid)ans = max(ans , query(L ,R , rson));
else
{
ans = max(ans , query(L ,R , lson));
ans = max(ans , query(L ,R , rson));
int ll , rr;
if(mid - L + 1 >= rsum[rt << 1])
{
ll = rsum[rt << 1];
}
else ll = mid - L + 1;
if(R - mid >= lsum[rt << 1 | 1])
{
rr = lsum[rt << 1 | 1];
}
else rr = R - mid;
ans = max(ans , max(ll , rr));
if(A[mid] < A[mid + 1])
{
ans = max(ans ,ll + rr);
}
}
return ans;
}
int main()
{
//ios::sync_with_stdio(false);
#ifdef Online_Judge
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif // Online_Judge
cin >> T;
while(T--)
{
scanf("%d%d" , &n , &m);
FORR(i , 1 , n)scanf("%d" , &A[i]);
build(1 , n , 1);
char s[5];
while(m--)
{
scanf("%s%d%d" , s ,&a , &b);
if(s[0] == 'U')
{
A[a + 1] = b;
update(a + 1 , 1 , n , 1);
}
else
{
int ans = query(a + 1 , b + 1 , 1 ,n , 1);
printf("%d\n" , ans);
}
}
}
return 0;
}