您的位置:首页 > 运维架构

HDU 3308 LCIS 线段树维护区间lcs

2016-05-31 21:45 459 查看
题意:

给一个1~n的数组

操作i把下标为x的值更新为y

操作ii查询区间 x~y的lcs

具体分析写在代码里

///参考讨论版

ACcode:

#include <cstdio>
#include <algorithm>
#define tmp (st<<1)
#define mid ((l+r)>>1)
#define lson l,mid,tmp
#define rson mid+1,r,tmp|1
#define len (r-l+1)
#define maxn 100002
using namespace std;
int my[maxn],sum[maxn<<2],lsum[maxn<<2],rsum[maxn<<2];
inline void push_up(int st,int l,int r){
lsum[st]=lsum[tmp];
rsum[st]=rsum[tmp|1];
sum[st]=max(sum[tmp],sum[tmp|1]);
if(my[mid]<my[mid+1]){///如果第mid+1大于mid 那么对于左子树的右lcs和右子树的左lcs可以合并
if(lsum[st]==len-(len>>1))lsum[st]+=lsum[tmp|1];
if(rsum[st]==len>>1)rsum[st]+=rsum[tmp];

sum[st]=max(sum[st],lsum[tmp|1]+rsum[tmp]);
}
}
inline void build(int l,int r,int st){
if(l==r){
sum[st]=lsum[st]=rsum[st]=1;
return ;
}
build(lson);
build(rson);
push_up(st,l,r);
}
inline void updata(int t,int l,int r,int st){
if(l==r)return ;
if(t<=mid)updata(t,lson);
if(t>mid)updata(t,rson);
push_up(st,l,r);
}
inline int query(int L,int R,int l,int r,int st){
if(L<=l&&r<=R)return sum[st];
if(R<=mid)return query(L,R,lson);
if(L>mid)return query(L,R,rson);
int ans,lans,rans;
lans=query(L,R,lson);
rans=query(L,R,rson);
ans=max(lans,rans);
if(my[mid]<my[mid+1]){///同上
int temp=min(rsum[tmp],mid-L+1)+min(lsum[tmp|1],R-mid);
ans=max(ans,temp);
}
return ans;
}
int main(){
int loop,n,q,x,y;
char str[4];
scanf("%d",&loop);
while(loop--){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;++i)scanf("%d",&my[i]);
build(1,n,1);
while(q--){
scanf("%s%d%d",str,&x,&y);
if(str[0]=='Q')
printf("%d\n",query(++x,++y,1,n,1));
else{
my[++x]=y;
updata(x,1,n,1);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: