zoukankan      html  css  js  c++  java
  • SP1716 GSS3

    Link

    SP1716 GSS3 - Can you answer these queries III

    Solve

    看到题的第一想法就是线段树,主要是要维护什么东西。

    因为一个答案和是否紧靠左右有关,我们就可以维护4个信息,区间和(sum),区间内最大值(max),紧靠左端点的区间最大值(lmax),紧靠右端点的区间最大值(rmax)我们只需要修改一下上传的信息的(pushup())即可。

    c[x].sum=c[x<<1].sum+c[x<<1|1].sum;
    c[x].lmax=max(c[x<<1].lmax,c[x<<1].sum+c[x<<1|1].lmax);
    c[x].rmax=max(c[x<<1|1].rmax,c[x<<1|1].sum+c[x<<1].rmax);
    c[x].max=max(c[x<<1].max,max(c[x<<1|1].max,c[x<<1].rmax+c[x<<1|1].lmax)); 
    

    注意统计答案时也要遵循(pushup)的规律,如果(l)$mid$和$mid$+$1$(r)都有分布的话要开一个(res)统计一下,(query)的时候一定要注意。

    Code

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=50005;
    int N,Q,a[maxn];
    struct node{
    	int l,r,sum,lmax,rmax,max;
    }c[maxn<<2];
    
    inline int read(){
    	int ret=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
    	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
    	return ret*f;
    }
    void pushup(int x){
    	c[x].sum=c[x<<1].sum+c[x<<1|1].sum;
    	c[x].lmax=max(c[x<<1].lmax,c[x<<1].sum+c[x<<1|1].lmax);
    	c[x].rmax=max(c[x<<1|1].rmax,c[x<<1|1].sum+c[x<<1].rmax);
    	c[x].max=max(c[x<<1].max,max(c[x<<1|1].max,c[x<<1].rmax+c[x<<1|1].lmax)); 
    }
    void build(int x,int l,int r){
    	c[x].l=l,c[x].r=r;
    	if(l==r){
    		c[x].sum=c[x].lmax=c[x].rmax=c[x].max=a[l];
    		return ;
    	}
    	int mid=(r-l>>1)+l;
    	build(x<<1,l,mid);
    	build(x<<1|1,mid+1,r);
    	pushup(x);
    }
    void change(int x,int u,int v){
    	if(c[x].l==c[x].r){
    		c[x].lmax=c[x].rmax=c[x].max=c[x].sum=v;
    		return ;
    	}
    	int mid=(c[x].r-c[x].l>>1)+c[x].l;
    	if(u<=mid)change(x<<1,u,v);
    	else change(x<<1|1,u,v);
    	pushup(x);
    }
    node query(int x,int L,int R){
    	if(L<=c[x].l&&c[x].r<=R)return c[x];
    	int mid=(c[x].r-c[x].l>>1)+c[x].l;
    	if(R<=mid)return query(x<<1,L,R);
    	if(mid<L)return query(x<<1|1,L,R);
    	node L_tree=query(x<<1,L,mid),R_tree=query(x<<1|1,mid+1,R),res;
    	res.sum=L_tree.sum+R_tree.sum;
    	res.lmax=max(L_tree.lmax,L_tree.sum+R_tree.lmax);
    	res.rmax=max(R_tree.rmax,R_tree.sum+L_tree.rmax);
    	res.max=max(L_tree.rmax+R_tree.lmax,max(L_tree.max,R_tree.max));
    	return res;
    }
    int main(){
    	freopen("SP1716.in","r",stdin);
    	freopen("SP1716.out","w",stdout);
    	N=read();
    	for(int i=1;i<=N;i++)a[i]=read();
    	Q=read();
    	build(1,1,N);
    	while(Q--){
    		 int op=read(),x=read(),y=read();
    		 if(op==0)change(1,x,y);
    		 else printf("%d
    ",query(1,x,y).max);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    c语言关键字-static
    c语言关键字-const
    c语言32个关键字
    宏定义#define详解
    c程序启动终止过程及exit(),_exit(),atexit()函数区别
    c语言编译过程和头文件<>与""的区别
    职业经理人-以柔克刚的柔性领导力
    职业经理人-如何管理好你的老板
    职业经理人-带人要带心
    职业经理人-怎样能批评了下属还让他很高兴
  • 原文地址:https://www.cnblogs.com/martian148/p/13879942.html
Copyright © 2011-2022 走看看