• AW245 你能回答这些问题吗(连续子段和线段树)


    题目地址


    易错点:

    • 建树递归到叶节点后,初始化时要注意不要漏掉某个元素.
    • 查询时要注意不要用反元素名称(rx -> lx).
    • 查询时a和b只需要reset a和b(ans不需要).

    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int MAXN=1e6,MAXM=2e5,INF=0x3f3f3f3f,root=1;
    struct Node{
    	int l,r;
    	int s,lx,rx;
    	int ans;
    	void reset(){
    		l=r=s=lx=rx=ans=-INF;
    	}
    }tr[MAXN*4];
    int a[MAXN];
    void build(int p,int l,int r){
    	tr[p].l=l,tr[p].r=r;
    	if(l==r){
    		tr[p].s=tr[p].lx=tr[p].rx=tr[p].ans=a[l];
    		return;
    	}
    	int mid=(tr[p].l+tr[p].r)>>1;
    	build(p<<1,l,mid);
    	build((p<<1)|1,mid+1,r);
    	tr[p].s=tr[p<<1].s+tr[(p<<1)|1].s;
    	tr[p].lx=max(tr[p<<1].lx,tr[p<<1].s+tr[(p<<1)|1].lx);
    	tr[p].rx=max(tr[(p<<1)|1].rx,tr[(p<<1)|1].s+tr[p<<1].rx);
    	tr[p].ans=max(max(tr[p<<1].ans,tr[(p<<1)|1].ans),tr[p<<1].rx+tr[(p<<1)|1].lx);
    }
    void change(int p,int x,int val){
    	if(tr[p].l==tr[p].r){
    		tr[p].s=tr[p].lx=tr[p].rx=tr[p].ans=val;
    		return;
    	}
    	int mid=(tr[p].l+tr[p].r)>>1;
    	if(x<=mid)change(p<<1,x,val);
    	else change((p<<1)|1,x,val);
    	tr[p].s=tr[p<<1].s+tr[(p<<1)|1].s;
    	tr[p].lx=max(tr[p<<1].lx,tr[p<<1].s+tr[(p<<1)|1].lx);
    	tr[p].rx=max(tr[(p<<1)|1].rx,tr[(p<<1)|1].s+tr[p<<1].rx);
    	tr[p].ans=max(max(tr[p<<1].ans,tr[(p<<1)|1].ans),tr[p<<1].rx+tr[(p<<1)|1].lx);
    }
    Node query(int p,int l,int r){
    	if(tr[p].l>=l&&tr[p].r<=r){
    		return tr[p];
    	}
    	int mid=(tr[p].l+tr[p].r)>>1;
    	Node a,b,ans;
    	a.reset(),
    	b.reset();
    	ans.s=0;
    	if(l<=mid){
    		a=query(p<<1,l,r);
    		ans.s+=a.s;
    	}
    	if(r>mid){
    		b=query((p<<1)|1,l,r);
    		ans.s+=b.s;
    	}
    	ans.lx=max(a.lx,a.s+b.lx);
    	ans.rx=max(b.rx,b.s+a.rx);
    	ans.ans=max(max(a.ans,b.ans),a.rx+b.lx);
    	return ans;
    }
    int main(){
    	int n,m;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    	}
    	build(root,1,n);
    	for(int i=1;i<=m;i++){
    		int k,x,y;
    		scanf("%d%d%d",&k,&x,&y);
    		if(k==1){//query
    			if(x>y)swap(x,y);
    			printf("%d
    ",query(root,x,y).ans);
    		}else if(k==2){//change
    			change(root,x,y);
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    sql常用函数
    sql数据库查询
    数据库增删改查
    数据库基本概念
    C#总结
    C#结构体
    C#常用函数类
    初识函数
    C#冒泡排序 折半查找
    12月27日笔记
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680533.html
Copyright © 2020-2023  润新知