zoukankan      html  css  js  c++  java
  • 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);
        }
    }
  • 相关阅读:
    种类并查集
    因式分解
    最长递增(不减)子序列
    C++之算法题模板
    线段树
    C++之环境搭建
    C++之vector用法
    逆序数以及右边更小数的个数
    Unity3d之动态连接Mesh Renderer和Collider
    Matlab之字符串处理
  • 原文地址:https://www.cnblogs.com/renjianshige/p/7351552.html
Copyright © 2011-2022 走看看