Black Rock Shooter 题解
题目描述
在人气动漫 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,输出一个整数代表最大值
题解
有题目可知这道题要求最大区间子段和,考虑用线段树维护。
对于线段树的每个节点,我们要储存四个信息:
typedef struct Node
{
int l, r;
long long lsum, rsum, msum, sum;
//lsum:从左边开始的最长子段和
//rsum:从右边开始的最长子段和
//msum:整个区间中的最长子段和
//sum:整个区间的子段和
Node *lson, *rson;
Node(): l(), r(), lsum(), rsum(), msum(), lson(NULL), rson(NULL), sum() {}
int len() {return r - l;}
int mid() {return (l + r) >> ;}
}node, *pointer;
对于每个变量,我们要在PushUp操作中进行维护:
void PsuhUp(pointer rt)
{
rt->sum = rt->lson->sum + rt->rson->sum;
//和的维护是直接维护
rt->lsum = std::max(rt->lson->lsum, rt->lson->sum + rt->rson->lsum);
//从左边开始的最长子段和有可能就是左边的最长子段和也有可能是整个左子树加上右子树的左边最长子段和
rt->rsum = std::max(rt->rson->rsum, rt->rson->sum + rt->lson->rsum);
//右边同理
rt->msum = std::max(rt->lson->rsum + rt->rson->lsum, std::max(rt->lson->msum, rt->rson->msum));
//中间的最长子段和除了要比较左右子树的两个之外,还要考虑将两个子树区间合并后新产生的的一个子段
}
最麻烦的是查询操作,同样也分为两种情况:
一种是在一个区间的中间的最长子段和,一种是有两个子树的左右最长子段和拼起来的。
//前面两个query操作是为了考虑第二种情况
LL QueryR(pointer rt, LL x, LL y)
{
if(rt->l >= x && y >= rt->r) return rt->rsum;
LL ans = QueryR(rt->rson, x, y);
if(x < rt->mid()) ans = std::max(ans, QueryR(rt->lson, x, y) + rt->rson->sum);
return ans;
} LL QueryL(pointer rt, LL x, LL y)
{
if(rt->l >= x && y >= rt->r) return rt->lsum;
LL ans = QueryL(rt->lson, x, y);
if(y > rt->mid()) ans = std::max(ans, QueryL(rt->rson, x, y) + rt->lson->sum);
return ans;
} LL Query(pointer rt, LL x, LL y)
{
if(x <= rt->l && rt->r <= y) return rt->msum;
LL ans = -0x7fffffff;
if(y <= rt->mid()) ans = Query(rt ->lson, x, y); //整个区间都在左子树上
else if(x >= rt->mid()) ans = Query(rt->rson, x, y); //整个区间都在右子树上
else ans = std::max(QueryR(rt->lson, x, y) + QueryL(rt->rson, x, y), std::max(Query(rt->lson, x, y), Query(rt->rson, x, y)));
//区间分布在左右子树上
return ans;
}
代码
#include <bits/stdc++.h>
using namespace std;
#define LL long long const int MAX = ;
typedef struct Node
{
int l, r;
long long lsum, rsum, msum, sum;
Node *lson, *rson;
Node(): l(), r(), lsum(), rsum(), msum(), lson(NULL), rson(NULL), sum(NULL) {}
int len() {return r - l;}
int mid() {return (l + r) >> ;}
}node, *pointer; class Segement_Tree
{
private:
void PsuhUp(pointer rt)
{
rt->sum = rt->lson->sum + rt->rson->sum;
rt->lsum = max(rt->lson->lsum, rt->lson->sum + rt->rson->lsum);
rt->rsum = max(rt->rson->rsum, rt->rson->sum + rt->lson->rsum);
rt->msum = max(rt->lson->rsum + rt->rson->lsum, max(rt->lson->msum, rt->rson->msum));
} LL QueryR(pointer rt, LL x, LL y)
{
if(rt->l >= x && y >= rt->r) return rt->rsum;
LL ans = QueryR(rt->rson, x, y);
if(x < rt->mid()) ans = max(ans, QueryR(rt->lson, x, y) + rt->rson->sum);
return ans;
} LL QueryL(pointer rt, LL x, LL y)
{
if(rt->l >= x && y >= rt->r) return rt->lsum;
LL ans = QueryL(rt->lson, x, y);
if(y > rt->mid()) ans = max(ans, QueryL(rt->rson, x, y) + rt->lson->sum);
return ans;
} public:
pointer root = new Node();
LL a[MAX]; void Build(pointer rt, int l, int r)
{
rt->r = r, rt->l = l;
if(r - l == )
{
rt->lsum = a[l], rt->rsum = a[l], rt->msum = a[l], rt->sum = a[l];
return ;
}
rt->lson = new Node(), rt->rson = new Node();
Build(rt->lson, l, rt->mid()), Build(rt->rson, rt->mid(), r);
PsuhUp(rt);
return ;
} void Updata(pointer rt, LL x, LL y)
{
if(rt->r - rt->l == && rt->l == x)
{
rt->lsum = y, rt->rsum = y, rt->msum = y, rt->sum = y;
return ;
}
if(x < rt->mid()) Updata(rt->lson, x, y);
else Updata(rt->rson, x, y);
PsuhUp(rt);
} LL Query(pointer rt, LL x, LL y)
{
if(x <= rt->l && rt->r <= y) return rt->msum;
LL ans = -0x7fffffff;
if(y <= rt->mid()) ans = Query(rt ->lson, x, y);
else if(x >= rt->mid()) ans = Query(rt->rson, x, y);
else ans = max(QueryR(rt->lson, x, y) + QueryL(rt->rson, x, y), max(Query(rt->lson, x, y), Query(rt->rson, x, y)));
return ans;
}
}; Segement_Tree tree; inline long long Qread()
{
long long x = ; int w = ; char ch = getchar();
for(;!isdigit(ch); w |= (ch == '-'), ch= getchar());
for(;isdigit(ch);x = (x << ) + (x << ) + (ch ^ ), ch = getchar());
return w ? -x : x;
} inline int qread()
{
int x = ; int w = ; char ch = getchar();
for(;!isdigit(ch); w |= (ch == '-'), ch= getchar());
for(;isdigit(ch);x = (x << ) + (x << ) + (ch ^ ), ch = getchar());
return w ? -x : x;
} int main()
{
// freopen("BRS.in", "r", stdin);
// freopen("BRS.out", "w", stdout); int n, m;
LL opt, x, y;
memset(tree.a, , sizeof(tree.a));
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++ i) tree.a[i] = Qread();
tree.Build(tree.root, , n + );
for(int i = ; i <= m; ++ i)
{
opt = Qread(), x = Qread(), y = Qread();
if(opt == ) printf("%lld\n", tree.Query(tree.root, x, y + ));
if(opt == ) tree.Updata(tree.root, x, y);
}
}
Black Rock Shooter 题解的更多相关文章
- Black Rock Shooter
在人气动漫 Black Rock shooter 中,当加贺里对麻陶 说出了"滚回去"以后,与此同时,在另一个心灵世界里, BRS 也遭到了敌人的攻击.此时,一共有 n 个攻击排成 ...
- Noip前的大抱佛脚----赛前任务
赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...
- 【题解】CF1426E Rock, Paper, Scissors
题目戳我 \(\text{Solution:}\) 考虑第二问,赢的局数最小,即输和平的局数最多. 考虑网络流,\(1,2,3\)表示\(Alice\)选择的三种可能性,\(4,5,6\)同理. 它们 ...
- Codeforces Round #672 (Div. 2) B. Rock and Lever题解(思维+位运算)
题目链接 题目大意 给你一个长为n(n<=1e5)的数组,让你求有多少对a[i]和a[j] (i!=j)满足a[i]&a[j]>a[i]^a[j] 题目思路 这些有关位运算的题目肯 ...
- 题解 CF1426E - Rock, Paper, Scissors
一眼题. 第一问很简单吧,就是每个 \(\tt Alice\) 能赢的都尽量让他赢. 第二问很简单吧,就是让 \(\tt Alice\) 输的或平局的尽量多,于是跑个网络最大流.\(1 - 3\) 的 ...
- CF1225E题解 Rock Is Push
在打CF的时候没想到www这个dp真的蛮巧妙的 这是一道dp题(废话 假设我们走到了\((i,j)\)位置,因为我们只能下移/右移,那么我们所有上方与左方的石块(即\(\{ (i,j)|i<n ...
- POJ - 2339 Rock, Scissors, Paper
初看题目时就发了个错误,我因为没有耐心看题而不了解题目本身的意思,找不到做题的突破口,即使看了一些题解,还是没有想到方法. 后来在去问安叔,安叔一语道破天机,问我有没有搞清题目的意思,我才恍然大悟,做 ...
- 2016 ACM/ICPC Asia Regional Qingdao Online(2016ACM青岛网络赛部分题解)
2016 ACM/ICPC Asia Regional Qingdao Online(部分题解) 5878---I Count Two Three http://acm.hdu.edu.cn/show ...
- 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 H题 Rock Paper Scissors Lizard Spock.(FFT字符串匹配)
2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...
随机推荐
- request-statistics.lua
--[[ 实现请求统计,并且将单位时间内异常次数达到阀值的请求加入到黑名单中 --]] --获取共享内存 local limit_req_store = ngx.shared.limit_req_st ...
- C. Molly's Chemicals
题目链接:http://codeforces.com/problemset/problem/776/C C. Molly's Chemicals time limit per test 2.5 sec ...
- 前端性能优化插件 --- PageSpeed Insights
对于前端工程师来说,前端性能优化始终都是非常重要的一环,它决定了用户体验, 决定了一个用户是否愿意在页面的加载浪费时间, 从而丢失用户. 所以前端性能优化是非常重要的. 下载地址 https://ch ...
- Android ContentProvider的介绍(很详细)
博客分类: android进阶 一.ContentProvider的概念 ContentProvider:为存储和获取数据提供统一的接口.可以在不同的应用程序之间共享数据.Android已经为常见 ...
- React.js 小书 Lesson11 - 配置组件的 props
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson11 转载请注明出处,保留原文链接和作者信息. 组件是相互独立.可复用的单元,一个组件可能在不 ...
- BJFU 1549 ——Candy——————【想法题】
Candy 时间限制(C/C++):1000MS/3000MS 运行内存限制:65536KByte总提交:40 测试通过:20 描述 There are N c ...
- MYSQL冷知识——ON DUPLICATE KEY 批量增删改
一 有个需求要批量增删改,并且是混合的,也就是仅不存在才增. 删简单,因为有个deleteStaute之类的字段,删除本质上就是就是一个修改 所以就是实现批量混合增改,然而组长说mysql不支持混合增 ...
- 弹性布局学习-详解 align-items(四)
目录 弹性布局学习-介绍(一) 弹性布局学习-详解 flex-direction[决定主轴的方向](二) 弹性布局学习-详解 justify-content(三) 弹性布局学习-详解 align-i ...
- 08.详细说明关键字new
关键字new有两个使用方法: (1).实例化对象 (2).显示的隐藏父类中的同名方法. 来自为知笔记(Wiz)
- Java的API及Object
API: Java API就是JDK中提供给我们使用的类,这些类将底层的代码实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可. 源文件使用方法: Object类概述: O ...