zoukankan      html  css  js  c++  java
  • SP1716 GSS3

    题意:给定n个数a[1]~a[n],有q次操作。

               操作 0 x y:把第a[x]修改为y;

               操作 1 x y:询问x到y的的最大子段和。

    输入:第一行:一个正整数n,表示有n个整数;

               第二行:n个整数,表示数列;

               第三行:一个正整数q,表示有q个询问;

               第4~q+3行:每行三个数p,x,y,表示三种操作。

    输出:对于每一个种类为1的询问,输出最大子段和。

    输入样例:

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

    输出样例:

    6
    4
    -3

    解析:用线段树进行维护,记录下每一段的和(sum),最大子段和(maxv),最大前缀(prefix),最大后缀(suffix)。则

              sum[o] = sum[o<<1] + sum[o<<1|1] ;

              maxv[o] = max( max( maxv[o<<1] , maxv[o<<1|1] ) , suffix[o<<1] + prefix[o<<1|1] ) ;

              prefix[o] = max( prefix[o<<1] , sum[o<<1] + prefix[o<<1|1] ) ;

              suffix[o] = max( suffix[o<<1|1] , suffix[o<<1] + sum[o<<1|1] ) 。最好统计答案即可。

    代码如下:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define lc o<<1
     4 #define rc o<<1|1
     5 using namespace std;
     6 
     7 const int MAXN=50010;
     8 int n,a[MAXN],q,prefix[MAXN*4],suffix[MAXN*4],maxv[MAXN*4],sum[MAXN*4],ans,pre;
     9 
    10 int read(void) {
    11     char c; while (c=getchar(),(c<'0' || c>'9') && c!='-'); int x=0,y=1;
    12     if (c=='-') y=-1; else x=c-'0';
    13     while (c=getchar(),c>='0' && c<='9') x=x*10+c-'0'; return x*y; 
    14 }
    15 
    16 void maintain(int o,int l,int r) { //维护 
    17     prefix[o]=max(prefix[lc],sum[lc]+prefix[rc]);
    18     suffix[o]=max(suffix[rc],sum[rc]+suffix[lc]);
    19     maxv[o]=max(maxv[lc],max(maxv[rc],suffix[lc]+prefix[rc]));
    20     sum[o]=sum[lc]+sum[rc];
    21 }
    22 
    23 void build(int o,int l,int r) { //建树 
    24     if (l==r) {
    25       prefix[o]=a[l];
    26       suffix[o]=a[l];
    27       maxv[o]=a[l];
    28       sum[o]=a[l];
    29       return;
    30     }
    31     int mid=l+r>>1;
    32       build(lc,l,mid); build(rc,mid+1,r);
    33     maintain(o,l,r);
    34 }
    35 
    36 void modify(int o,int l,int r,int p,int x) { //单点修改 
    37     if (l==r) {
    38       prefix[o]=x;
    39       suffix[o]=x;
    40       maxv[o]=x;
    41       sum[o]=x;
    42       return;
    43     }
    44     int mid=l+r>>1;
    45       if (p<=mid) modify(lc,l,mid,p,x); else modify(rc,mid+1,r,p,x);
    46     maintain(o,l,r);
    47 }
    48 
    49 void query(int o,int l,int r,int ql,int qr) { //区间查询 
    50     if (ql<=l && qr>=r) { //分三种情况考虑,统计答案 
    51       ans=max(ans,maxv[o]);
    52       ans=max(ans,pre+prefix[o]);
    53       pre=max(pre+sum[o],suffix[o]);
    54       return;
    55     }
    56     int mid=l+r>>1;
    57     if (ql<=mid) query(lc,l,mid,ql,qr);
    58     if (qr>mid) query(rc,mid+1,r,ql,qr);
    59 }
    60 
    61 int main() {
    62     n=read();
    63       for (int i=1;i<=n;++i) a[i]=read();
    64     build(1,1,n);
    65     q=read();
    66       while (q--) {
    67           int p=read(),x=read(),y=read();
    68             if (p) {
    69                   ans=pre=-2e9;
    70                   query(1,1,n,x,y);
    71                   printf("%d
    ",ans);
    72             }
    73           else {
    74               modify(1,1,n,x,y);
    75           }
    76       }
    77     return 0;
    78 }
  • 相关阅读:
    装饰者模式
    Linux top命令
    Java基础--单例类创建和测试
    Mybatis动态sql
    bmp图片格式及读取
    自然语言处理--nltk安装及wordnet使用详解
    Spring注解
    struts2 + spring + mybatis 框架整合
    Java基础--ThreadLocal
    Java基础--压缩和解压缩gz包
  • 原文地址:https://www.cnblogs.com/Gaxc/p/9737816.html
Copyright © 2011-2022 走看看