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\n",hh.ans); } else change(1,y,z); } }