1 条题解

  • 0
    @ 2025-8-24 22:45:17

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Autream
    读书和抽大麻没有区别,都是捧着死掉的植物产生幻觉。

    搬运于2025-08-24 22:45:17,当前版本为作者最后更新于2024-03-11 21:44:54,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题意简述

    给定一个长度为 nn 的序列 aa,其中 aia_i 表示一个序列中连续 ii 个元素的最大值,求这个序列,可能有多种解。如果有解,输出任意一种;否则输出 NIE


    题目分析

    看到这种有 Special Judge 的题目首先就得想到构造。

    我们假设所有情况都是有解的,那么对于一个序列 bb,我们可以假设 bb 的前 ii 项的和就是连续 ii 项的最大值,也就是题目所给的 aia_i,那么这个构造柿子就显而易见了。

    因为 bb 的前 ii 项的和是 aia_i,并且此时 bb 中只有 ii 个数,所以对于连续 i+1i+1 个数的最大值,我们只能添加一个数,使得前 i+1i+1 项的和为 ai+1a_{i+1},这个数显然就是 ai+1j=1ibja_{i+1}-\sum\limits_{j=1}^{i}b_j。也就是 bi=aiai1b_i=a_i-a_{i-1}

    接下来我们再来考虑不合法的情况。

    因为我们表示的 j=1ibj\sum\limits_{j=1}^{i}b_j 是连续 ii 项的和,那么如果在更新到第 i+1i+1 项的时候,在这 i+1i+1 项中有连续的 j[1,i]j \in [1,i] 项的最大值大于了 aia_i 那么就不合法。例如下面这组数据:

    5
    3 1 4 1 5
    

    当我们按照上面的构造柿子构造到最后一项时,bb 数组为:

    3 -2 3 -3 4

    可以发现最后四项的和为 22,大于题目给的 a4=1a_4=1,故不符合条件。

    区间和用前缀和统计即可。


    AC Code

    #include<bits/stdc++.h>
    #define arrout(a,n) rep(i,1,n)std::cout<<a[i]<<" "
    #define arrin(a,n) rep(i,1,n)std::cin>>a[i]
    #define rep(i,x,n) for(int i=x;i<=n;i++)
    #define dep(i,x,n) for(int i=x;i>=n;i--)
    #define erg(i,x) for(int i=head[x];i;i=e[i].nex)
    #define dbg(x) std::cout<<#x<<":"<<x<<" "
    #define mem(a,x) memset(a,x,sizeof a)
    #define all(x) x.begin(),x.end()
    #define arrall(a,n) a+1,a+1+n
    #define PII std::pair<int,int>
    #define m_p std::make_pair
    #define u_b upper_bound
    #define l_b lower_bound
    #define p_b push_back
    #define CD const double
    #define CI const int
    #define int long long
    #define il inline
    #define ss second
    #define ff first
    #define itn int
    CI N=1e5+5;
    int n,a[N],b[N],s[N];
    signed main() {
        std::cin>>n;
        arrin(a,n);
        rep(i,1,n){
            b[i]=a[i]-a[i-1];
            s[i]=s[i-1]+b[i];
            rep(len,1,i){
                rep(l,1,i-len+1){
                    int r=l+len-1;
                    if(s[r]-s[l-1]>a[len]){
                        puts("NIE");
                        exit(0);
                    }
                }
            }
        }
        puts("TAK");
        std::cout<<n<<"\n";
        arrout(b,n);
        return 0;
    }
    
    • 1

    信息

    ID
    8398
    时间
    1000ms
    内存
    128MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者