区间 (interval)【牛客小白月赛5】

链接:https://www.nowcoder.com/acm/contest/135/I
来源:牛客网
 

题目描述

    Apojacsleam喜欢数组。

    他现在有一个n个元素的数组a,而他要对a[L]-a[R]进行M次操作:

        操作一:将a[L]-a[R]内的元素都加上P

        操作二:将a[L]-a[R]内的元素都减去P

    最后询问a[l]-a[r]内的元素之和?

    请认真看题干及输入描述。

输入描述:

输入共M+3行:

第一行两个数,n,M,意义如“题目描述”

第二行n个数,描述数组。

第3-M+2行,共M行,每行四个数,q,L,R,P,若q为1则表示执行操作2,否则为执行操作1

第4行,两个正整数l,r

输出描述:

一个正整数,为a[l]-a[r]内的元素之和

  思路:

  我们知道了要进行M次操作和左后所要查找的区间范围【l,r】不如先把所有区间存起来,然后从后往前一一处理这些范围加减的数,为了避免超时,我在处理【l,r】的原数的和的时候用了下前缀和(不用应该也没关系反正O(n)的复杂度)。

完整代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
int N,M;
struct node
{
    int q,l,r,p;
}ti[1000002];
ll a[1000002];
int L,R;
ll panp(int x)
{
    if(x==1) return (-1);
    else return 1;
}
int main()
{
    while(scanf("%d%d",&N,&M)!=EOF)
    {
        memset(a, 0, sizeof(a));
        for(int i=1; i<=N; i++)
        {
            scanf("%lld",&a[i]);
            a[i]+=a[i-1];
        }
        for(int i=1; i<=M; i++)
        {
            scanf("%lld%lld%lld%lld", &ti[i].q, &ti[i].l, &ti[i].r, &ti[i].p);
        }
        scanf("%d%d",&L,&R);
        ll sum=a[R]-a[L-1];
        for(int i=1; i<=M; i++)
        {
            if(ti[i].l<=L && ti[i].r<=R && ti[i].r>=L)
            {
                sum=sum+(ti[i].r-L+1)*panp(ti[i].q)*ti[i].p;
            }
            else if(ti[i].l<=L && ti[i].r>=R)
            {
                sum=sum+(R-L+1)*panp(ti[i].q)*ti[i].p;
            }
            else if(ti[i].l>=L && ti[i].r<=R)
            {
                sum=sum+(ti[i].r-ti[i].l+1)*panp(ti[i].q)*ti[i].p;
            }
            else if(ti[i].r>=R && ti[i].l<=R)
            {
                sum=sum+(R-ti[i].l+1)*panp(ti[i].q)*ti[i].p;
            }
        }
        printf("%lld\n",sum);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41730082/article/details/81263473