zoukankan      html  css  js  c++  java
  • SP1716 GSS3

    题意翻译

    (n) 个数,(q) 次操作

    操作(0) (x) (y)(A_x) 修改为(y)

    操作(1) (l) (r)询问区间([l, r])的最大子段和

    输入输出格式

    输入格式:

    The first line of input contains an integer N. The following line contains N integers, representing the sequence A1..AN.
    The third line contains an integer M. The next M lines contain the operations in following form:
    0 x y: modify Ax into y (|y|<=10000).
    1 x y: print max{Ai + Ai+1 + .. + Aj | x<=i<=j<=y }.

    输出格式:

    For each query, print an integer as the problem required.

    输入输出样例

    输入样例#1:

    4
    1 2 3 4
    4
    1 1 3
    0 3 -3
    1 2 4
    1 3 3
    

    输出样例#1:

    6
    4
    -3
    

    思路:首先分析询问的本质:求出区间最大子段和!很显然我们可以使用线段树维护序列,本题的难点主要在如何进行上传操作,将子树(l)(r)的节点信息上传到子树(rt)时,对于(rt)维护的序列中,和最大的子段有两种情况:

    1. 子段不经过中点,那么 (rt) 的答案为 (l)(r) 的答案的最大值。
    2. 子段经过了中点。这种情况比较复杂,因为我们无法知道子树的答案所对应的序列。这也是本题的难点所在。

    然后我们用结构体板线段树来分情况维护一下最大字段和即可,结构体传址快。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #define maxn 50007
    #define ls rt<<1
    #define rs rt<<1|1
    using namespace std;
    inline int qread() {
      char c=getchar();int num=0,f=1;
      for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
      for(;isdigit(c);c=getchar()) num=num*10+c-'0';
      return num*f;
    }
    int n,m;
    struct Tree {
      int lmax,rmax,sum,maxx;
    }tree[maxn<<2];
    inline void pushup(int rt) {
      tree[rt].lmax=max(tree[ls].lmax,tree[ls].sum+tree[rs].lmax);
      tree[rt].rmax=max(tree[rs].rmax,tree[rs].sum+tree[ls].rmax);
      tree[rt].maxx=max(tree[ls].rmax+tree[rs].lmax,max(tree[ls].maxx,tree[rs].maxx));
      tree[rt].sum=tree[ls].sum+tree[rs].sum;
    }
    void build(int rt, int l, int r) {
      if(l==r) {
      	tree[rt].lmax=tree[rt].rmax=tree[rt].sum=tree[rt].maxx=qread();
      	return;
      }
      int mid=(l+r)>>1;
      build(ls,l,mid);
      build(rs,mid+1,r);
      pushup(rt);
    }
    void add(int rt, int l, int r, int L, int val) {
      if(l==r) {
      	tree[rt].lmax=tree[rt].rmax=tree[rt].sum=tree[rt].maxx=val;
      	return;
      }
      int mid=(l+r)>>1;
      if(L<=mid) add(ls,l,mid,L,val);
      else add(rs,mid+1,r,L,val);
      pushup(rt);
    }
    Tree query(int rt, int l, int r, int L, int R) {
      if(L==l&&r==R) return tree[rt];
      int mid=(l+r)>>1;
      if(L>mid) return query(rs,mid+1,r,L,R);
      else if(R<=mid) return query(ls,l,mid,L,R);
      else {
      	Tree a=query(ls,l,mid,L,mid),b=query(rs,mid+1,r,mid+1,R),c;
      	c.lmax=max(a.lmax,a.sum+b.lmax);
      	c.rmax=max(b.rmax,b.sum+a.rmax);
      	c.sum=a.sum+b.sum;
      	c.maxx=max(a.rmax+b.lmax,max(a.maxx,b.maxx));
      	return c;
      }
    }
    int main() {
      n=qread();
      build(1,1,n);
      m=qread();
      for(int i=1,k,x,y;i<=m;++i) {
      	k=qread(),x=qread(),y=qread();
      	if(!k) add(1,1,n,x,y);
      	else printf("%d
    ",query(1,1,n,x,y).maxx);
      }
      return 0;
    }
    
  • 相关阅读:
    VUE课程参考---2、VUE基本使用
    VUE课程---1、VUE课程介绍
    JS数组常用方法---3、pop方法使用及原理
    JavaScript中数组元素删除的七大方法汇总
    Stack的三种含义
    JS数组常用方法---6、reverse方法
    数据库水平切分的实现原理解析---分库,分表,主从,集群,负载均衡器
    服务框架HSF分析之一容器启动
    淘宝HSF服务的原理以及简单的实现
    DAS 原文出自【比特网】
  • 原文地址:https://www.cnblogs.com/grcyh/p/10201372.html
Copyright © 2011-2022 走看看