Black Rock shooter

题目大意
在人气动漫 Black Rock shooter 中,当加贺里对麻陶
说出了“滚回去“以后,与此同时,在另一个心灵世界里,
BRS 也遭到了敌人的攻击。此时,一共有 n 个攻击排成一行
朝着她飞了过来,每个攻击有一个伤害值。并且每个攻击伤
害可能随时变化。 BRS 的攻击可以打掉一段连续的攻击。现
在,给出 m 段攻击,求出 BRS 最多可以打掉此段里多少的
伤害(就是说从给定一段里选择连续一段打掉)。 伤害从 1
到 n 编号。
2.输入格式
第一行 2 个整数: n , m
第二行 n 个数:第 i 个数代表第 i 个攻击
第 3 到 2+m 行:每行三个数 k, x, y。若 k=1, x, y
代表查询的区间。若 k=2,代表第 x 个攻击伤害改为了 y
所有的伤害值绝对值<=1000
3.输出格式
对于每次 k=1, 输出一个整数代表最大值
4.样例输入
5 3
1 2 -3 4 5
1 2 3
2 2 -1
1 2 3
5.样例输出
-2
1
6.数据范围
对于 20%的数据: n, m<=100
对于 60%的数据: n, m<=3000
对于 100%的数据: n<=500000,m<=100000

题解:

好像有这个算法,用线段树维护最大连续区间和,可以自己去查一下。

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#define MAXN 500100
#define lson 2*xv
#define rson 2*xv+1
using namespace std;
struct tree{
    long long sum,l,r,ll,rr,ans;
}a[MAXN*6];
int zhi[MAXN];

void update(int xv){
    a[xv].sum=a[lson].sum+a[rson].sum;
    a[xv].ll=max(a[lson].ll,a[lson].sum+a[rson].ll);
    a[xv].rr=max(a[rson].rr,a[rson].sum+a[lson].rr);
    a[xv].ans=max(max(a[lson].ans,a[rson].ans),a[lson].rr+a[rson].ll);
}

void build(int xv,int l,int r){
    if(l==r){
        a[xv].l=l,a[xv].r=r;
        a[xv].ll=a[xv].rr=a[xv].ans=zhi[l];a[xv].sum=zhi[l];
        return;
    }
    a[xv].l=l,a[xv].r=r;
    int mid=(l+r)/2;
    build(xv*2,l,mid);build(xv*2+1,mid+1,r);
    update(xv);
}

tree query(int xv,int l,int r){
    int L=a[xv].l,R=a[xv].r,mid=(L+R)/2;
    if(l==L&&r==R){
        return a[xv];
    }
    if(r<=mid) return query(lson,l,r);
    if(l>mid) return query(rson,l,r);
    tree llson=query(lson,l,mid),rrson=query(rson,mid+1,r);
    tree hh;
    hh.sum=llson.sum+rrson.sum;
    hh.ll=max(llson.ll,llson.sum+rrson.ll);
    hh.rr=max(rrson.rr,rrson.sum+llson.rr);
    hh.ans=max(max(llson.ans,rrson.ans),llson.rr+rrson.ll);
    return hh;
}

void change(int xv,int pos,int hh){
    int L=a[xv].l,R=a[xv].r,mid=(L+R)/2;
    if(L==R&&L==pos){
        a[xv].ll=a[xv].rr=a[xv].ans=a[xv].sum=hh;
        return;
    }
    if(pos<=mid) change(lson,pos,hh);
    if(pos>mid) change(rson,pos,hh);
    update(xv);
}

int main(){
    int n,m;scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&zhi[i]);
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int x,y,z;scanf("%d%d%d",&x,&y,&z);
        if(x==1) {
            tree hh=query(1,y,z);
            printf("%lld
",hh.ans);
        }
        else change(1,y,z);
    }
}
原文地址:https://www.cnblogs.com/renjianshige/p/7351552.html