阿卡的萝卜

题目描述

阿卡是一只可爱的小白兔,今天是她第一次登场。她希望给大家留下深刻的印象,于是她就来直播种萝卜和吃 萝卜了。
阿卡家的菜田被分成若干长条形状,其中只有一块地上种了她爱吃的萝卜。至于其他菜地,种的都是辣条、土 豆泥、鸡翅一类阿卡不感兴趣的食物,阿卡是不会走到那些地方去的。 这条菜地上一共种了 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;
}
 

猜你喜欢

转载自blog.csdn.net/yhhy666/article/details/108220931