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;
    }
    
  • 相关阅读:
    HDU 6143 Killer Names【dp递推】【好题】【思维题】【阅读题】
    HDU 6143 Killer Names【dp递推】【好题】【思维题】【阅读题】
    POJ 3974 Palindrome【manacher】【模板题】【模板】
    POJ 3974 Palindrome【manacher】【模板题】【模板】
    HDU 6127 Hard challenge【计算机几何】【思维题】
    HDU 6127 Hard challenge【计算机几何】【思维题】
    HDU 6129 Just do it【杨辉三角】【思维题】【好题】
    HDU 6129 Just do it【杨辉三角】【思维题】【好题】
    HDU 3037 Saving Beans【Lucas定理】【模板题】【模板】【组合数取余】
    8.Math 对象
  • 原文地址:https://www.cnblogs.com/grcyh/p/10201372.html
Copyright © 2011-2022 走看看