题目描述
阿卡是一只可爱的小白兔,今天是她第一次登场。她希望给大家留下深刻的印象,于是她就来直播种萝卜和吃 萝卜了。
阿卡家的菜田被分成若干长条形状,其中只有一块地上种了她爱吃的萝卜。至于其他菜地,种的都是辣条、土 豆泥、鸡翅一类阿卡不感兴趣的食物,阿卡是不会走到那些地方去的。 这条菜地上一共种了 n 株萝卜,这些萝卜从前到后被阿卡标号被 1 号萝卜、2 号萝卜… n 号萝卜。每个萝卜 目前有一个美味值 Ai。阿卡首先要直播种萝卜,他会进行 m 个操作,每个操作都是以下两种之一,
J l r , 表示阿卡为标号为 l ≤ i ≤ r 的每一个萝卜都浇了一次水。其中 1 ≤ l ≤ r ≤ n。浇水能够使萝卜 的肉质更加鲜美,因此一个萝卜每被浇一次水都会增加 1 个单位的美味值。 H l r, 阿卡有时除虫会很烦躁,就会在萝卜上倒农药。这个操作表示阿卡为标号为 l ≤ i ≤ r 的每一个 萝卜都喷了一些农药。其中 1 ≤ l ≤ r ≤ n。这个操作会使萝卜丧失掉一些信仰,因此一个萝卜每被喷一 次农药都会减少 1 个单位的美味值。注意,在有些时刻,可能会有一些萝卜的美味值为负数,这也是被允 许的。
经过了这 m 个操作之后,阿卡就会结束他种萝卜的直播。
阿卡吃萝卜是很挑剔的,她只吃连续的一段萝卜,并且她只关心她吃到的所有萝卜的美味值的和。也就是说, 她将要吃的是一段连续的,美味值之和最大的萝卜。
在直播的最后,阿卡为了检验她有没有给你留下深刻的印象,出了这么一道题:她所吃的萝卜的美味值之和是 多少。可你早就不记得了。你记得的只有兔阿卡的每一次操作和萝卜田初始的状态,你能回答她的问题吗
输入
第一行,一个整数 n,表示萝卜的个数。
第二行,n 个整数 Ai (1 ≤ i ≤ n),分别表示每一个位置上萝卜的初始美味值。
第三行,一个整数 m,表示阿卡操作的个数。
接下来 m 行,每行格式如题目描述中所述,保证第一个字符为 C 和 > 之一,保证 1 ≤ l ≤ r ≤ n。
输出
一个整数表示阿卡所吃的萝卜的美味值之和。
样例输入
5
7 -9 -9 -5 -9
8
J 2 2
J 2 3
J 1 3
J 1 3
J 3 3
J 2 3
J 1 5
J 2 4
10
读题发现暴力要TLE,所以复杂的至少要到O(nlongn)
1.线段树,进行区间加减操作
_2.数学方式左端点++,右端点+1–,最后算前缀和求解;
举个例子:
3
1 2 3
1
J 1 2
sum[1]++;
sum[3]–;
sum[1]+sum[0]=1;a[1]+sum[1]=1+1=2;
sum[2]+sum[1]=1;a[2]+sum[2]=2+1=3;
sum[3]+sum[2]=0;a[3]+sum[3]=3+0;
输出:2 3 3
最后O(N)最大字段和
#include<bits/stdc++.h>
using namespace std;
int num[550000];
int n;
int a[550000];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
int k;cin>>k;
for(int i=1;i<=k;i++)
{
char c;int l,r;
cin>>c>>l>>r;
int f;
if(c=='J')f=1;
else f=-1;
num[l]+=f;num[r+1]-=f;
}
for(int i=1;i<=n;i++)num[i]+=num[i-1],a[i]+=num[i];//前缀求和
int ans=0,maxx=-0x7fffffff;
for(int i=1;i<=n;i++)//最大字段和
{
ans=max(a[i],ans+a[i]);
maxx=max(maxx,ans);
}
cout<<maxx;
return 0;
}