Codeforces 1166 D. Cute Sequences 构造

这场好有毒啊~进去就被C、E俩结论题关了。

赛后补题发现其实D也很容易构造。

题意是请你构造一个长度在50以内的序列,第一项是a,最后一项是b,序列的每一项都是前缀和再加上$r_{i}$,然后规定$1<=r_{i}<=m$。

显然我们可以发现在$r_{i}$对$x_{j}$的贡献是非常容易计算的

for(i=1;i<=50;i++)for(i0=0;i0<i;i0++)dic[i]+=dic[i0];

 用dic[i]表示$r_{p}$对$x_{p+i}$的贡献。

然后我们要规定序列的长度,这个的话,我是求出每个长度的上下界,如果b在上下界内,这个长度就可行,如果b大于上界后同时也大于下界,那显然就要输出-1。

有了长度之后我们就直接求解每一项的具体值即可,在原来的上界的基础上,我们可以减回$[0,m-1]$,来使得$x_{n}$符合我们的要求减小到b。

以下是具体实现代码:

#include<bits/stdc++.h>
using namespace std;
int i,i0,n;
long long L[55],R[55],preL[55],preR[55],dic[55];
int main()
{
    dic[0]=1;
    for(i=1;i<=50;i++)for(i0=0;i0<i;i0++)dic[i]+=dic[i0];
    int T;
    scanf("%d",&T);
    while(T--)
    {
        long long a,b,m;
        scanf("%lld %lld %lld",&a,&b,&m);
        preL[1]=L[1]=preR[1]=R[1]=a;
        if(a==b)
        {
            printf("1 %lld\n",a);
            continue;
        }
        for(i=2;1;i++)
        {
            L[i]=preL[i-1]+1;
            preL[i]=preL[i-1]+L[i];
            R[i]=preR[i-1]+m;
            preR[i]=preR[i-1]+R[i];
            if(R[i]>=b)break;
        }
        if(L[i]>b)printf("-1\n");
        else
        {
            n=i;
            for(i=2;i<=n;i++)
            {
                if(R[n]>b)
                {
                    long long d=min(m-1,(R[n]-b)/dic[n-i]);
                    for(i0=i;i0<=n;i0++)R[i0]-=d*dic[i0-i];
                }
            }
            printf("%d",n);
            for(i=1;i<=n;i++)printf(" %lld",R[i]);
            printf("\n");
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/megalovania/p/10888493.html