• 2020/10/30 模拟赛 序列


    Description

    淘淘在研究极差,即可重集的最大值减最小值(这个定义应该都知道吧)。 蓝蓝有一个数列 $a_1,a_2,cdots ,a_n$。他想考考淘淘是否真的理解了极差,就让淘淘把他划分为若干子区间(可以退化为一个数,但不能退化为空集),并最大化这些子区间极差之和。 由于他的数列太长了,他用某种方法来表示这个序列,详情请见输入格式。 又由于他的数列太长了,他只需要淘淘告诉他这个最大值的和。

    Solution

    题中要求一个序列划分为数段,每一段的极差之和

    发现如果有一段不单调,可以将其划分得到更优的答案;如果一段单调,继续划分不会使答案更优

    从前到后扫数组,考虑每一位作为一个单调区间的最小值或最大值两种情况

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int n,x,y,z,b[10000005],a[10000005],m;
    long long ans,maxx,minn;
    inline int read()
    {
        int f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            w=(w<<1)+(w<<3)+ch-'0';
            ch=getchar();
        }
        return f*w;
    }
    int main()
    {
        n=read(),x=read(),y=read(),z=read(),b[1]=read(),b[2]=read(),m=read();
        for(int i=3;i<=n;i++)
        {
            b[i]=(1ll*x*b[i-1]+1ll*y*b[i-2]+z)%(1<<30);
        }
        for(int i=1,j=1;i<=m;i++)
        {
            int p=read(),l=read(),r=read();
            while(j<=p)
            {
                a[j]=b[j]%(r-l+1)+l,++j;
            }
        }
        minn=-a[1],maxx=a[1];
        for(int i=1;i<=n;i++)
        {
            ans=max(minn+a[i],maxx-a[i]);
            minn=max(minn,ans-a[i+1]);
            maxx=max(maxx,ans+a[i+1]);
        }
        printf("%lld
    ",ans);
        return 0;
    }
    序列
  • 相关阅读:
    3月18
    线段树求后继+环——cf1237D
    排序+stl——cf1237C
    思维+双指针+环——cf1244F
    模拟+双指针——cf1244E
    树的性质——cf1244D
    数学思维——cf1244C
    树的直径变形——cf1238F
    ac自动机暴力跳fail匹配——hdu5880
    状态压缩dp增量统计贡献——cf1238E(好题)
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/13956230.html
Copyright © 2020-2023  润新知