地址: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): 2941 Accepted Submission(s): 1282
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
题意:求区间内最大连续递增子序列。
先自己做了遍,但是一直WA,找不到错哪了。然后找了大牛的代码看了下,好高端,自己写了下。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define M 100050
#define LL L,m,c<<1
#define RR m+1,R,c<<1|1
#define max(a,b) a>b?a:b
struct node{
int lm,rm,sm;
};
int lm[M*5],rm[M*5],sm[M*5],da[M];
void push(int L,int R,int c)
{
int m=(L+R)>>1;
lm[c]=lm[c<<1];rm[c]=rm[c<<1|1];
sm[c]=max(sm[c<<1],sm[c<<1|1]);
if(da[m]<da[m+1])
{
if(lm[c<<1]==m-L+1) lm[c]+=lm[c<<1|1];
if(rm[c<<1|1]==R-m) rm[c]+=rm[c<<1];
sm[c]=max(sm[c],rm[c<<1]+lm[c<<1|1]);
}
}
void ori_tree(int L,int R,int c)
{
int m=(L+R)>>1;
if(L==R)
{
scanf("%d",&da[L]);
lm[c]=rm[c]=sm[c]=1;
//printf("%d %d %d %d %d\n",L,R,lm[c],rm[c],sm[c]);
}
else
{
ori_tree(LL);
ori_tree(RR);
push(L,R,c);
//printf("%d %d %d %d %d\n",L,R,lm[c],rm[c],sm[c]);
}
}
void updata(int i,int num,int L,int R,int c)
{
if(L==R)
da[L]=num;
else
{
int m=(L+R)>>1;
if(i<=m) updata(i,num,LL);
else updata(i,num,RR);
push(L,R,c);
}
}
node sum(int l,int r,int L,int R,int c)
{
node lv,rv,sv;
if(L==l&&R==r)
{
sv.lm=lm[c];
sv.rm=rm[c];
sv.sm=sm[c];
return sv;
}
else
{
int m=(L+R)>>1;
if(r<=m) return sum(l,r,LL);
else if(l>m) return sum(l,r,RR);
else
{
lv=sum(l,m,LL);
rv=sum(m+1,r,RR);
sv.lm=lv.lm;sv.rm=rv.rm;
sv.sm=max(lv.sm,rv.sm);
if(da[m]<da[m+1])
{
if(lv.lm==m-L+1) sv.lm+=rv.lm;
if(rv.rm==R-m) sv.rm+=lv.rm;
sv.sm=max(sv.sm,lv.rm+rv.lm);
}
return sv;
}
}
}
int main()
{
int t,m,n,l,r;
char str[20];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&m,&n);
ori_tree(1,m,1);
while(n--)
{
scanf("%s%d%d",str,&l,&r);
if(str[0]=='Q')
printf("%d\n",sum(l+1,r+1,1,m,1).sm);
else updata(l+1,r,1,m,1);
}
}
return 0;
}