线段树的区间并,这道题是比较简单的一个,,重点是细节的处理
#include<bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define sf scanf
#define pf printf
#define mem(a,b) memset(a,b,sizeof(a));
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define MP make_pair
#define ULL unsigned long long
#define LL long long
#define inf 0x3f3f3f3f
#define md ((ll[i]+rr[i])>>1)
#define ls (i<<1)
#define rs (ls|1)
#define eps 1e-5
#define N 200050
#define ree freopen("in.txt","r",stdin);
#define bug pf("----------------");
//2017年09月25日21:29:24
int ll[N<<2],rr[N<<2],a[N],lx[N<<2],rx[N<<2],mx[N<<2];
int n,m;
int len(int i){
return rr[i]-ll[i]+1;
}
void up(int i){
mx[i]=max(mx[ls],mx[rs]);
if(a[md]<a[md+1]){
mx[i]=max(mx[i],rx[ls]+lx[rs]);
if(lx[ls]==len(ls))
lx[i]=len(ls)+lx[rs];
else
lx[i]=lx[ls];
if(rx[rs]==len(rs))
rx[i]=len(rs)+rx[ls];
else
rx[i]=rx[rs];
}
else{
lx[i]=lx[ls],rx[i]=rx[rs];
}
}
void build(int l,int r,int i){
ll[i]=l,rr[i]=r;
if(l==r){
mx[i]=lx[i]=rx[i]=1;
return ;
}
build(l,md,ls);build(md+1,r,rs);
up(i);
}
void update(int p,int val,int i){
if(ll[i]==rr[i])return ;
if(p<=md)
update(p,val,ls);
else
update(p,val,rs);
up(i);
}
int query(int l,int r,int i){
if(ll[i]==l&&rr[i]==r)
return mx[i];
if(r<=md)return query(l,r,ls);
if(l>md)return query(l,r,rs);
if(a[md]>=a[md+1])
return max(query(l,md,ls),query(md+1,r,rs));
int ret=max(query(l,md,ls),query(md+1,r,rs));
int head=max(l,md-rx[ls]+1);
int tail=min(r,md+lx[rs]);
ret=max(ret,tail-head+1);
return ret;
}
int main(){
//ree
int cas;
sf("%d",&cas);
while(cas--){
sf("%d%d",&n,&m);
for(int i=1;i<=n;++i)sf("%d",&a[i]);
build(1,n,1);
int k,v,l,r;
while(m--){
char op[2];sf("%s",op);
if(op[0]=='Q'){
sf("%d%d",&l,&r);
l++;r++;
pf("%d\n",query(l,r,1));
continue;
}
sf("%d%d",&k,&v);
k++; a[k]=v;
update(k,v,1);
}
}
}
本文介绍了一种基于线段树的数据结构实现——区间并,用于解决特定类型的区间操作问题。通过详细的代码解析,读者可以了解到如何利用线段树进行区间合并及查询最大连续区间的长度。文章适用于有一定数据结构基础的学习者。
576

被折叠的 条评论
为什么被折叠?



