此版本有更新操作 la3938 只是查询而已所以la3938可以上dp
但是有更新操作就上不了了
为嘛? 因为
DP 插入 O(1) 扫描O(n) 和 为O(n)
segment tree 插入O(logn) 扫描 O(logn) 和 为O(2*logn)
化简一下 可以发现 DP(2^n) > > segment tree(n*n)
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200009
using namespace std;
struct node//如果是uvalive 3938那就加一个 maxl,maxr用来记录maxi的范围 在pushup刷新这两个值 query也记得刷一下
{
int maxi,lmax,rmax,sum;
} tree[4*N];
void pushup(int rt)//刷新rt节点的数据 相当于lrj的minv
{
tree[rt].sum=tree[rt*2].sum+tree[rt*2+1].sum;
tree[rt].maxi=max(tree[rt*2].maxi,max(tree[rt*2+1].maxi,tree[rt*2].rmax+tree[rt*2+1].lmax));
tree[rt].lmax=max(tree[rt*2].lmax,tree[rt*2].sum+tree[rt*2+1].lmax);
tree[rt].rmax=max(tree[rt*2+1].rmax,tree[rt*2+1].sum+tree[rt*2].rmax);
}
void init_tree(int l,int r,int rt)
{
if(l==r)
{
scanf("%d",&tree[rt].sum);
tree[rt].maxi=tree[rt].rmax=tree[rt].lmax=tree[rt].sum;
return;
}
int mid=(r+l)/2;
init_tree(l,mid,rt*2);
init_tree(mid+1,r,rt*2+1);
pushup(rt);
}
void updata(int l,int r,int value,int position,int rt)
{
int mid=(r+l)/2;
if(l==r)
{
tree[rt].maxi=tree[rt].rmax=tree[rt].lmax=tree[rt].sum=value;
return;
}
else
{
if(position<=mid)//根据位置确定递归方向
{
updata(l,mid,value,position,rt*2);
}
else
{
updata(mid+1,r,value,position,rt*2+1);
}
pushup(rt);
}
}
node query(int l,int r,int aa,int bb,int rt)
{
int mid=(l+r)/2;
if(aa<=l&&bb>=r)
{
return tree[rt];
}/*为了个毛线段树的搜索为logn? 原因出在这里, 当被搜索树节点的区间被查询范围覆盖时,直接return,不必完整展开下面的
子树(节点)*/
node ka,kb,res;
int flaga=0,flagb=0;
if(aa<=mid)
{
ka=query(l,mid,aa,bb,rt*2);//分割子树(砍一半) 左 (查询左端点小于中值)
flaga=1;
}
if(bb>mid)
{
kb=query(mid+1,r,aa,bb,rt*2+1);// 分割子树(砍一半)右(查询右端点大于中值)
flagb=1;
}
if(flaga&&flagb)//此st节点的左右都查了 合并结果
{
res.sum=ka.sum+kb.sum;
res.lmax=max(ka.lmax,ka.sum+kb.lmax);
res.rmax=max(kb.rmax,kb.sum+ka.rmax);
res.maxi=max(ka.maxi,max(kb.maxi,ka.rmax+kb.lmax));
}
else
{
if(flaga)//st节点只有左子树
res=ka;
if(flagb)//st节点只有右子树
res=kb;
}
return res;
}
int main()
{
int n,m,op,aa,bb;
while(~scanf("%d%d",&n,&m))
{
init_tree(1,n,1);
/*for(int i=1;i<=n;i++)
printf("%d\n",tree[i].maxi);*/
while(m--)
{
scanf("%d%d%d",&op,&aa,&bb);
if(op==1)
{
node res=query(1,n,aa,bb,1);
printf("%d\n",res.maxi);
}
else
{
updata(1,n,bb,aa,1);
/*for(int i=1;i<=n;i++)
printf("%d\n",tree[i].maxi);
*/
}
}
}
return 0;
}