zoukankan      html  css  js  c++  java
  • $Luogu$ $P4513$ 小白逛公园

    链接

    背景

    (huhao)(Luogu) (P4513)

    题意

    给定一个数列,要求单点修改、区间查询最大子段和。

    解法

    线段树单点修改、区间查询模板。维护每个区间和 (sum) 、区间最大子段和 (val) 、区间从左端点开始向右的最大子段和 (lmax) 、区间从右端点开始向左的最大子段和 (rmax)

    (trick)

    查询时先加入一个节点,后来查询到的节点直接与该节点比较更新即可。

    细节

    (1.) 建树和修改时各个信息均要赋值。(好傻逼的错误啊)

    (2.) 查询中比较更新时注意各信息顺序,修改时要用到别的信息值的先更新。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    inline int read()
    {
    	int ret=0,f=1;
    	char ch=getchar();
    	while(ch>'9'||ch<'0')
    	{
    		if(ch=='-')
    			f=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9')
    	{
    		ret=(ret<<1)+(ret<<3)+ch-'0';
    		ch=getchar();
    	}
    	return ret*f;
    }
    int n,q,a[500005],op,x,val,l,r,ans;
    bool flag;
    struct SegmentTree
    {
    	int l;
    	int r;
    	int val;
    	int sum;
    	int lmax;
    	int rmax;
    }t[2000005],tmp;
    void build(int pos,int l,int r)
    {
    	t[pos].l=l;
    	t[pos].r=r;
    	if(l==r)
    	{
    		t[pos].sum=a[l];
    		t[pos].lmax=a[l];
    		t[pos].rmax=a[l];
    		t[pos].val=a[l];
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(pos<<1,l,mid);
    	build(pos<<1|1,mid+1,r);
    	t[pos].sum=t[pos<<1].sum+t[pos<<1|1].sum;
    	t[pos].lmax=max(t[pos<<1].lmax,t[pos<<1].sum+t[pos<<1|1].lmax);
    	t[pos].rmax=max(t[pos<<1|1].rmax,t[pos<<1].rmax+t[pos<<1|1].sum);
    	t[pos].val=max(max(t[pos<<1].val,t[pos<<1|1].val),t[pos<<1].rmax+t[pos<<1|1].lmax);
    }
    void modify(int pos,int x,int val)
    {
    	if(t[pos].l==t[pos].r)
    	{
    		t[pos].sum=val;
    		t[pos].lmax=val;
    		t[pos].rmax=val;
    		t[pos].val=val;
    		return;
    	}
    	int mid=(t[pos].l+t[pos].r)>>1;
    	if(x<=mid)
    		modify(pos<<1,x,val);
    	else
    		modify(pos<<1|1,x,val);
    	t[pos].sum=t[pos<<1].sum+t[pos<<1|1].sum;
    	t[pos].lmax=max(t[pos<<1].lmax,t[pos<<1].sum+t[pos<<1|1].lmax);
    	t[pos].rmax=max(t[pos<<1|1].rmax,t[pos<<1].rmax+t[pos<<1|1].sum);
    	t[pos].val=max(max(t[pos<<1].val,t[pos<<1|1].val),t[pos<<1].rmax+t[pos<<1|1].lmax);
    }
    void query(int pos,int l,int r)
    {
    	if(t[pos].l>=l&&t[pos].r<=r)
    	{
    		if(!flag)
    		{
    			flag=1;
    			tmp=t[pos];
    		}
    		else
    		{
    			tmp.lmax=max(tmp.lmax,tmp.sum+t[pos].lmax);
    			tmp.sum=tmp.sum+t[pos].sum;
    			tmp.val=max(max(tmp.val,t[pos].val),tmp.rmax+t[pos].lmax);
    			tmp.rmax=max(t[pos].rmax,tmp.rmax+t[pos].sum);
    		}
    		return;
    	}
    	int mid=(t[pos].l+t[pos].r)>>1;
    	if(l<=mid)
    		query(pos<<1,l,r);
    	if(r>mid)
    		query(pos<<1|1,l,r);
    }
    int main()
    {
    	n=read();
    	q=read();
    	for(register int i=1;i<=n;i++)
    		a[i]=read();
    	build(1,1,n);
    	while(q--)
    	{
    		op=read();
    		if(op==2)
    		{
    			x=read();
    			val=read();
    			modify(1,x,val);
    		}
    		else
    		{
    			l=read();
    			r=read();
    			if(l>r)
    				swap(l,r);
    			flag=0;
    			query(1,l,r);
    			printf("%d
    ",tmp.val);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    初识nginx
    Keepalived 配置实例
    ssh学习小记
    代码开发、测试及发布
    需求改进&系统设计
    软件设计原则、设计模式学习+部分实现
    自我介绍+课程 6 问
    python函数嵌套出现报错UnboundLocalError原理的猜测(有解决办法,但是对于报错原理不确定)
    python tkinter 问题(多个Listbox选取显示问题,虚拟事件的特点为何虚拟,listbox.nearest函数与虚拟事件绑定返回值错误,StringVar类参数调用时单向性,线程无响应)
    python tkinter pack布局遇到的错误和问题总结(无图)
  • 原文地址:https://www.cnblogs.com/Peter0701/p/11332412.html
Copyright © 2011-2022 走看看