Black Rock Shooter

本文介绍了一种使用线段树解决区间最大子段和问题的方法,通过维护区间最大子段和的三个关键值(lm, rm, mx),实现对区间内数值的快速更新与查询。适用于数据动态变化的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在人气动漫 Black Rock shooter 中,当加贺里对麻陶
说出了“滚回去“以后,与此同时,在另一个心灵世界里,
BRS 也遭到了敌人的攻击。此时,一共有 n 个攻击排成一行
朝着她飞了过来,每个攻击有一个伤害值。并且每个攻击伤
害可能随时变化。BRS 的攻击可以打掉一段连续的攻击。现
在,给出 m 段攻击,求出 BRS 最多可以打掉此段里多少的
伤害(就是说从给定一段里选择连续一段打掉)。伤害从 1
到 n 编号。

输入格式

第一行 2 个整数:n , m
第二行 n 个数:第 i 个数代表第 i 个攻击
第 3 到 2+m 行:每行三个数 k,x,y。若 k=1,x,y
代表查询的区间。若 k=2,代表第 x 个攻击伤害改为了 y
所有的伤害值绝对值<=1000

输出格式

对于每次 k=1,输出一个整数代表最大值

样例输入

5 3
1 2 -3 4 5
1 2 3
2 2 -1
1 2 3

样例输出

2
-1

数据范围
对于 20%的数据:n,m<=100
对于 60%的数据:n,m<=3000
对于 100%的数据:n<=500000,m<=100000

【题解】
这道题应该是一道有点裸的线段树,只是将模板的求和换作求最大值而已。即用线段树维护区间最大子段和。
solution写法:区间合并线段树,维护lm,rm,mx.

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAX=500005;
struct tree
{
    int sum;//本段总和
    int v;//本段中自身的最大子段
    int vl,vr;//本段连接左或右端点的最大子段
}t[MAX<<2];
int N,M,k,x,y;

int gi()
{
    int x=0,w=1;char ch=getchar();
    while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if (ch=='-') w=-1,ch=getchar();
    while (ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*w;
}

void Update(int now)
{
    int lson=now<<1,rson=now<<1|1;
    t[now].v=max(t[lson].vr+t[rson].vl,max(t[lson].v,t[rson].v));
    t[now].vl=max(t[lson].vl,t[lson].sum+t[rson].vl);
    t[now].vr=max(t[rson].vr,t[rson].sum+t[lson].vr);
    t[now].sum=t[lson].sum+t[rson].sum;
}

void Build(int now,int l,int r)
{
    if (l==r)
    {
        t[now].sum=t[now].v=t[now].vl=t[now].vr=gi();
        return;
    }
    int mid=(l+r)>>1;
    Build(now<<1,l,mid);
    Build(now<<1|1,mid+1,r);
    Update(now);
}

int Query_l(int now,int l,int r)//查询左连续的最大子段
{
    if (l>=x&&r<=y)
         return t[now].vl;
    int mid=(l+r)>>1,res;
    res=Query_l(now<<1,l,mid);
    if (y>mid) res=max(res,t[now<<1].sum+Query_l(now<<1|1,mid+1,r));
    return res;
}

int Query_r(int now,int l,int r)//查询右连续的最大子段
{
    if (l>=x&&r<=y)
        return t[now].vr;
    int mid=(l+r)>>1,res;
    res=Query_r(now<<1|1,mid+1,r);
    if (x<=mid) res=max(res,t[now<<1|1].sum+Query_r(now<<1,l,mid));
    return res;
}

//x y是询问区间
int Query(int now,int l,int r)//区间最大子段
{
    if (l>=x&&r<=y)
        return t[now].v;
    int mid=(l+r)>>1,res;
    if (y<=mid) res=Query(now<<1,l,mid);
    else if (x>mid) res=Query(now<<1|1,mid+1,r);
    else res=max(Query_r(now<<1,l,mid)+Query_l(now<<1|1,mid+1,r),max(Query(now<<1,l,mid),Query(now<<1|1,mid+1,r)));
    return res;
}

//把第x个数修改成y
void Change(int now,int l,int r)
{
    if (l==r)
    {
        t[now].sum=t[now].v=t[now].vl=t[now].vr=y;
        return;
    }
    int mid=(l+r)>>1;
    if (x<=mid) Change(now<<1,l,mid);
    else Change(now<<1|1,mid+1,r);
    Update(now);
}

int main()
{
    freopen("BRS.in","r",stdin);
    freopen("BRS.out","w",stdout);
    N=gi();M=gi();
    Build(1,1,N);
    while (M--)
    {
        k=gi();x=gi();y=gi();
        if (k==1)
            printf("%d\n",Query(1,1,N));
        else
            Change(1,1,N);
    }
    return 0;
}
内容概要:本文针对国内加密货币市场预测研究较少的现状,采用BP神经网络构建了CCi30指数预测模型。研究选取2018年3月1日至2019年3月26日共391天的数据作为样本,通过“试凑法”确定最优隐结点数目,建立三层BP神经网络模型对CCi30指数收盘价进行预测。论文详细介绍了数据预处理、模型构建、训练及评估过程,包括数据归一化、特征工程、模型架构设计(如输入层、隐藏层、输出层)、模型编译与训练、模型评估(如RMSE、MAE计算)以及结果可视化。研究表明,该模型在短期内能较准确地预测指数变化趋势。此外,文章还讨论了隐层节点数的优化方法及其对预测性能的影响,并提出了若干改进建议,如引入更多技术指标、优化模型架构、尝试其他时序模型等。 适合人群:对加密货币市场预测感兴趣的研究人员、投资者及具备一定编程基础的数据分析师。 使用场景及目标:①为加密货币市场投资者提供一种新的预测工具和方法;②帮助研究人员理解BP神经网络在时间序列预测中的应用;③为后续研究提供改进方向,如数据增强、模型优化、特征工程等。 其他说明:尽管该模型在短期内表现出良好的预测性能,但仍存在一定局限性,如样本量较小、未考虑外部因素影响等。因此,在实际应用中需谨慎对待模型预测结果,并结合其他分析工具共同决策。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值