2020 计蒜之道 预赛 第一场 B. 染色(简单)

2020 计蒜之道 预赛 第一场 B. 染色(简单)

题目链接

本题保证 m 个区间两两不相交。

小 P 得到了一个长为 n 的序列,序列元素编号 1 … n 1\dots n 1n。小 P 想给这个序列的每个元素染上黑 白两种颜色之一,于是他就随便制定了一个染色方案。正当小 P 要染色时,小 A 批判道:“Naive!这个染色方案太难看了,你应该仔细分析染色的效果之后再动手。” 小 A 和小 P 一起分析序列的性质之后,得出两个结论:

序列中的第 ii 个位置染成黑色会产生 b i b_i bi 的美感,染成白色会产生 w i w_i wi 的美感。
有些区间比较特殊,如果区间内的所有数都染成黑色会额外得到 c i c_i ci 的美感;另一些区间则恰好相反,如果区间内的所有数都染成白色会额外得到 c i c_i ci 的美感。
小 A 和小 P 想知道美感总和的最大值,请你帮他们求出这个值。

输入格式

第一行两个整数 n,m,分别表示序列的长度和特殊区间的数量。

第二行 n 个整数 b i b_i bi,表示每个位置染成黑色会得到的美感。

第三行 n 个整数 w i w_i wi,表示每个位置染成白色会得到的美感。

接下来下 m 行,每行四个整数 t i , l i , r i , c i t_i,l_i,r_i,c_i ti,li,ri,ci t i = 1 t_i=1 ti=1 表示如果区间 [ l i , r i ] [l_i,r_i] [li,ri] 都被染成黑色会额外得到 c i c_i ci 的美感, t i = 2 t_i=2 ti=2 则表示如果区间 [ l i , r i ] [l_i,r_i] [li,ri] 都被染成白色会额外得到 c i c_i ci 的美感。

输出格式

输出一行一个整数,表示美感总和的最大值。

数据范围与约定

保证 0 ≤ n , m ≤ 3 × 1 0 5 , 1 ≤ l i ≤ r i ≤ n , − 1 0 9 ≤ w i , b i ≤ 1 0 9 , t i ∈ { 1 , 2 } , 1 ≤ c i ≤ 1 0 9 0\leq n,m\leq 3\times 10^5,1\leq l_i\leq r_i\leq n,-10^9\leq w_i,b_i\leq 10^9,t_i\in \{1,2\},1\leq c_i\leq 10^9 0n,m3×105,1lirin,109wi,bi109,ti{ 1,2},1ci109
本题保证 m 个区间两两不相交。

样例输入

5 2
1 2 2 4 3
0 -2 7 1 5
2 1 2 7
1 5 5 1

样例输出

21

因为保证区间不相交,所以可以直接预处理前缀和,根据判断每个位置的上色情况,AC代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+5;
ll k,ans[N],a[N],b[N],sum1[N],sum2[N],sum3[N],sum=0;
int main()
{
    
    
    int n,m,op,l,r;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]),sum1[i]=sum1[i-1]+a[i];
    for(int i=1;i<=n;i++) scanf("%lld",&b[i]),sum2[i]=sum2[i-1]+b[i];
    for(int i=1;i<=n;i++) ans[i]=max(a[i],b[i]),sum3[i]=ans[i]+sum3[i-1];
    while(m--){
    
    
        scanf("%d%d%d%lld",&op,&l,&r,&k);
        if(op==1){
    
    
            if(sum1[r]-sum1[l-1]+k>sum3[r]-sum3[l-1]){
    
    
                for(int i=l;i<=r;i++) ans[i]=a[i];
                sum+=k;
            }
        }else{
    
    
            if(sum2[r]-sum2[l-1]+k>sum3[r]-sum3[l-1]){
    
    
                for(int i=l;i<=r;i++) ans[i]=b[i];
                sum+=k;
            }
        }
    }
    for(int i=1;i<=n;i++) sum+=ans[i];
    printf("%lld",sum);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43765333/article/details/108556256