您的位置:首页 > 其它

[HDU 3308] LCIS

2014-11-24 23:33 260 查看

LCIS

Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4437 Accepted Submission(s): 2006


[align=left]Problem Description[/align]
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].

[align=left]Input[/align]
T in the first line, indicating the case number.
Each case starts with two integers n , m(0<n,m<=105).
The next line has n integers(0<=val<=105).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=105)
OR
Q A B(0<=A<=B< n).

[align=left]Output[/align]
For each Q, output the answer.

[align=left]Sample Input[/align]

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

[align=left]Sample Output[/align]

1
1
4
2
3
1
2
5

线段树区间合并

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define N 100005

struct node
{
int l,r,m;
int ln,rn;
int lsum,rsum,msum;
int mid()
{
return (l+r)>>1;
}
}t[N<<2];
int a
;

void pushup(int rt)
{
t[rt].lsum=t[rt<<1].lsum;
t[rt].rsum=t[rt<<1|1].rsum;
t[rt].ln=t[rt<<1].ln;
t[rt].rn=t[rt<<1|1].rn;
t[rt].msum=max(t[rt<<1].msum,t[rt<<1|1].msum);
int ll=t[rt<<1].r-t[rt<<1].l+1;
int rr=t[rt<<1|1].r-t[rt<<1|1].l+1;

if(t[rt<<1].rn<t[rt<<1|1].ln)
{
if(t[rt<<1].lsum==ll)
t[rt].lsum+=t[rt<<1|1].lsum;
if(t[rt<<1|1].rsum==rr)
t[rt].rsum+=t[rt<<1].rsum;
t[rt].msum=max(t[rt].msum,t[rt<<1].rsum+t[rt<<1|1].lsum);
}
}
void build(int l,int r,int rt)
{
t[rt].l=l;
t[rt].r=r;
if(l==r)
{
t[rt].ln=t[rt].rn=a[l];
t[rt].lsum=t[rt].rsum=t[rt].msum=1;
return;
}
int m=t[rt].mid();
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
pushup(rt);
}
void update(int rt,int pos,int c)
{
if(t[rt].l==t[rt].r)
{
t[rt].ln=t[rt].rn=c;
return;
}
int m=t[rt].mid();
if(pos<=m) update(rt<<1,pos,c);
else update(rt<<1|1,pos,c);
pushup(rt);
}
int query(int rt,int L,int R)
{
if(t[rt].l==L && t[rt].r==R)
{
return t[rt].msum;
}
int m=t[rt].mid();
if(R<=m) return query(rt<<1,L,R);
else if(L>m) return query(rt<<1|1,L,R);
else
{
int sum=0,m=t[rt].mid();
int ltmp=query(rt<<1,L,m);
int rtmp=query(rt<<1|1,m+1,R);
if(t[rt<<1].rn<t[rt<<1|1].ln)       //注意:取最大值时要保证是在给定的区间[L,R]里面,左边,取min(全长,rsum),右边取min(全长,lsum)
{
sum=min(m-L+1,t[rt<<1].rsum)+min(R-m,t[rt<<1|1].lsum);
}
return max(max(ltmp,rtmp),sum);
}
}
int main()
{
int T,n,m,i;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
build(0,n-1,1);
while(m--)
{
char op;
int a,b;
scanf(" %c%d%d",&op,&a,&b);
if(op=='U') update(1,a,b);
else if(op=='Q') printf("%d\n",query(1,a,b));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: