题目链接: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): 9048 Accepted Submission(s): 3922
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 the case number.
Each case starts with two integers n , m(0<n,m<=).
The next line has n integers(0<=val<=).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=)
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
题意:n个数,m个操作,操作包括单点修改和区间查询最长递增子序列,对每个查询输出答案。
解法:使线段树上的每个区间维护从头开始的最长连续递增子序列的长度(lmax),从尾开始的倒序最长连续递减子序列的长度(rmax),以及区间最长递增子序列长度;
代码:
#include<iostream>
#include<cstdio>
#include<vector>
#include<bitset>
#include<stack>
#include<set>
#include<queue>
#include<map>
#include<cmath>
#include<string>
#include<cstring>
#include<ctime>
#include<fstream>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define pii pair<int, int>
#define mp(a,b) make_pair(a,b)
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define per(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a,b) for(int i=a;i>=b;i--)
#define PI 3.1415926535897932384626433832795
#define inf 0x3f3f3f3f
typedef long long ll;
const double eps=1.0e-5;
const int maxn=100000+10;
int t,n,m,a,b,ans,tmp,len;
char choice[10];
struct node{
int l,r;
int lx,rx; //lx是左端点值,rx是右端点值
int lmax,rmax,mmax;
}tree[maxn<<2];
void go_up(int k)
{
tree[k].lx=tree[k<<1].lx;tree[k].rx=tree[k<<1|1].rx;
if(tree[k<<1].lmax==tree[k<<1].r-tree[k<<1].l+1){
if(tree[k<<1].rx<tree[k<<1|1].lx){
tree[k].lmax=tree[k<<1].lmax+tree[k<<1|1].lmax;
}else{
tree[k].lmax=tree[k<<1].lmax;
}
}else{
tree[k].lmax=tree[k<<1].lmax;
}
if(tree[k<<1|1].rmax==tree[k<<1|1].r-tree[k<<1|1].l+1){
if(tree[k<<1|1].lx>tree[k<<1].rx){
tree[k].rmax=tree[k<<1].rmax+tree[k<<1|1].rmax;
}else{
tree[k].rmax=tree[k<<1|1].rmax;
}
}else{
tree[k].rmax=tree[k<<1|1].rmax;
}
tree[k].mmax=max(tree[k].lmax,max(tree[k].rmax,max(tree[k<<1].mmax,tree[k<<1|1].mmax)));
if(tree[k<<1].rx<tree[k<<1|1].lx) tree[k].mmax=max(tree[k].mmax,tree[k<<1].rmax+tree[k<<1|1].lmax);
}
void build(int le,int ri,int k)
{
tree[k].l=le,tree[k].r=ri;
if(le==ri){
scanf("%d",&tree[k].lx);
tree[k].rx=tree[k].lx;
tree[k].lmax=tree[k].rmax=tree[k].mmax=1;
return;
}
int mid=(le+ri)>>1;
build(le,mid,k<<1);
build(mid+1,ri,k<<1|1);
go_up(k);
}
void update(int k)
{
if(tree[k].l==tree[k].r){
tree[k].lmax=tree[k].rmax=tree[k].mmax=1;
tree[k].lx=tree[k].rx=b;
return;
}
int mid=(tree[k].l+tree[k].r)>>1;
if(a<=mid) update(k<<1);
else update(k<<1|1);
go_up(k);
}
void query(int k)
{
if(a<=tree[k].l&&tree[k].r<=b){
if(tree[k].lx>tmp){
if(tree[k].lmax==tree[k].r-tree[k].l+1){
len+=tree[k].lmax;
tmp=tree[k].rx;
ans=max(ans,len);
}
else{
len+=tree[k].lmax;
ans=max(ans,len);
len=tree[k].rmax;
tmp=tree[k].rx;
}
}else{
len=tree[k].rmax;
tmp=tree[k].rx;
ans=max(ans,len);
}
ans=max(ans,max(tree[k].lmax,max(tree[k].rmax,tree[k].mmax)));
return;
}
int mid=(tree[k].l+tree[k].r)>>1;
if(a<=mid) query(k<<1);
if(b>mid) query(k<<1|1);
}
int main()
{
//freopen("C:\\Users\\MAC\\Desktop\\in.txt","r",stdin);
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
build(1,n,1);
per(i,1,m){
scanf("%s %d %d",choice,&a,&b);
if(choice[0]=='Q'){
a++;b++;
ans=0;
tmp=inf;
query(1);
printf("%d\n",ans);
}else{
a++;
update(1);
}
}
}
}