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 ...
随机推荐
- journalctl 中文手册
版权声明 本文译者是一位开源理念的坚定支持者,所以本文虽然不是软件,但是遵照开源的精神发布. 无担保:本文译者不保证译文内容准确无误,亦不承担任何由于使用此文档所导致的损失. 自由使用:任何人都可以自 ...
- (转)shell--read命令的选项及用法
shell--read命令 原文:https://www.cnblogs.com/lottu/p/3962921.html http://blog.csdn.net/skdkjzz/article/d ...
- mongodb常用语句(集合操作)
mongodb常用语句(集合操作) 查看集合帮助 db.songs.help(); 查看集合总数据量 db.songs.count(); 查看表空间大小 db.songs.dataSize(); 查看 ...
- Programmer Competency Matrix--ref--http://sijinjoseph.com/programmer-competency-matrix/
Note that the knowledge for each level is cumulative; being atlevel n implies that you also know eve ...
- BNU34067——Pair——————【找规律】
Pair Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld Java class name: M ...
- Linux.net && mono
资料: http://www.cnblogs.com/xiaodiejinghong/archive/2013/04/01/2994216.html http://www.cnblogs.com/sh ...
- MVC5 下拉框绑定(单选)
1.Model [Display(Name = "学历")] public ICollection<System.Web.Mvc.SelectListItem> asd ...
- mysql三-1:理解存储引擎
一.什么是存储引擎 mysql中建立的库===>文件夹 库中建立的表===>文件 生活中我们用来存储数据的文件有不同的类型,每种文件类型对应各自不同的处理机制:比如处理文本用txt类型,处 ...
- mysql四-1:单表查询
一.单表查询的语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 二.关键 ...
- 前端给div加滚动条样式修改
<!DOCTYPE html> <html lang="en"> <head> <meta chars ...