这场好有毒啊~进去就被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;
}