您的位置:首页 > 其它

HDU 3308 LCIS(线段树)

2014-11-02 21:47 309 查看
题目:

Input:

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).

Output:

For each Q, output the answer.

题意:

此题要求实现对已存数据的更新和查询出给出的范围内最大递增区间的长度,故可以线段树成段更新来解决。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define MAX 100000
using namespace std;
int Max[MAX<<2],lmax[MAX<<2],rmax[MAX<<2],val[MAX],flag[MAX<<2];
void pushup(int l,int r,int root)
{
int mid=(l+r)>>1;
lmax[root]=lmax[root<<1];
rmax[root]=rmax[root<<1|1];
Max[root]=max(Max[root<<1],Max[root<<1|1]);
if(val[mid]<val[mid+1])
{
if(flag[root<<1])//左孩子满
lmax[root]+=lmax[root<<1|1];
if(flag[root<<1|1])//右孩子满
rmax[root]+=rmax[root<<1];
Max[root]=max(Max[root],rmax[root<<1]+lmax[root<<1|1]);//取父节点长度与左右孩子长度和的较大值
}
if(Max[root]==r-l+1)//此分支已为满
{
flag[root]=1;
}
else
{
flag[root]=0;
}
}
void buildtree(int l,int r,int root)
{
Max[root]=1;
lmax[root]=1;
rmax[root]=1;
flag[root]=1;
if(l==r)
{
scanf("%d",&val[l]);
return;
}
int mid=(l+r)>>1;
buildtree(l,mid,root<<1);
buildtree(mid+1,r,root<<1|1);
pushup(l,r,root);

}
void update(int l,int r,int root,int p,int re)
{
if(l==r)
{
val[p]=re;
return;
}
int mid=(l+r)>>1;
if(p<=mid)
{
update(l,mid,root<<1,p,re);
}
else{
update(mid+1,r,root<<1|1,p,re);
}
pushup(l,r,root);
}
int query(int l,int r,int root,int L,int R)
{
if(l>=L&&r<=R)//成段更新
{
return Max[root];
}
int mid=(l+r)>>1;
if(mid>=R)
{
return query(l,mid,root<<1,L,R);
}
if(mid<L)
{
return query(mid+1,r,root<<1|1,L,R);
}
int ans=max(query(l,mid,root<<1,L,mid),query(mid+1,r,root<<1|1,mid+1,R));//所查区间左右各有,取两者最大值
if(val[mid]<val[mid+1])//所查的中间点两边成递增的情况
{
ans=max(ans,min(mid-L+1,rmax[root<<1])+min(R-mid,lmax[root<<1|1]));//取区间两边长度最小值之和与之前没去两边的最大递增长度比较
}
return ans;
}
int main()
{
int n,m,T,num,a,b;
scanf("%d",&T);
char ch[10];
while(T--)
{
scanf("%d%d",&n,&m);
buildtree(1,n,1);
for(int i=1;i<=m;i++)
{
scanf("%s",&ch);
scanf("%d%d",&a,&b);
if(ch[0]=='U')
{
update(1,n,1,a+1,b);
}
else{
printf("%d\n",query(1,n,1,a+1,b+1));
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: