您的位置:首页 > 其它

hdu3308LCIS(线段树区间合并)

2013-03-22 18:01 274 查看
http://acm.hdu.edu.cn/showproblem.php?pid=3308

注意两个地方 向上更新 和查找的时候

向上更新

1. 左儿子最右边的值 < 右儿子最左边的值
View Code

#include <iostream>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<algorithm>
using namespace std;
#define N 100010
int s[N<<2],mm[N<<2],lm[N<<2],rm[N<<2],len[N<<2];
void update(int l,int r,int w)
{
int m = (l+r)>>1;
if(s[m]<s[m+1])
{
lm[w] = (lm[w<<1]==len[w<<1])?(lm[w<<1]+lm[w<<1|1]):lm[w<<1];
rm[w] = (rm[w<<1|1]==len[w<<1|1])?(rm[w<<1|1]+rm[w<<1]):rm[w<<1|1];
mm[w] = max((rm[w<<1]+lm[w<<1|1]),mm[w<<1]);
mm[w] = max(lm[w],mm[w]);
mm[w] = max(rm[w],mm[w]);
mm[w] = max(mm[w<<1|1],mm[w]);
}
else
{
lm[w] = lm[w<<1];
rm[w] = rm[w<<1|1];
mm[w] = max(mm[w<<1],mm[w<<1|1]);
}
}
int search(int a,int b,int l,int r,int w)
{
if(a<=l&&b>=r)
{
return mm[w];
}
int m = (l+r)>>1;
if(b<=m)
return search(a,b,l,m,w<<1);
if(a>m)
return search(a,b,m+1,r,w<<1|1);
int len,ren,ans ;
len = search(a,b,l,m,w<<1);
ren = search(a,b,m+1,r,w<<1|1);
ans = max(len,ren);
if(s[m]<s[m+1])
{
int re;
re=min(rm[w<<1],m-a+1)+min(lm[w<<1|1],b-m);
ans=max(re,ans);
}
return ans;
}
void build(int l,int r,int w)
{
len[w] = (r-l+1);
if(l==r)
{
mm[w] = 1;
lm[w] = 1;
rm[w] = 1;
return ;
}
int m = (l+r)>>1;
build(l,m,w<<1);
build(m+1,r,w<<1|1);
update(l,r,w);
}
void change(int p,int d,int l,int r,int w)
{
if(l==r&&l==p)
{
return ;
}
int m = (l+r)>>1;
if(p<=m)
change(p,d,l,m,w<<1);
else
change(p,d,m+1,r,w<<1|1);
update(l,r,w);
}
int main()
{
int i,j,k,n,m,t,a,b;
char c;
cin>>t;
while(t--)
{
cin>>n>>m;
for(i = 1; i <= n ; i++)
scanf("%d",&s[i]);
build(1,n,1);
while(m--)
{
cin>>c>>a>>b;
if(c=='U')
{
s[a+1] = b;
change(a+1,b,1,n,1);
}
else
{
cout<<search(a+1,b+1,1,n,1)<<endl;
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: