地址:https://codeforces.com/contest/1166/problem/D
思路:构造题。可以推出 2^p*(a+x)=b; x=[1,m],那么可以先遍历 p 找出 2^p*(a+m)<=b的最大值p1,在二分找出2^p1*(a+x)<=b的最大x1,当 x=0说明不能构造,否则得到 余数p=b-2^p1*(a+x1); 而a,b之间隔了 p1个数,每个数每次+x1可以最终得到d-p,用d[i]记录第i个数加的数字p1
而对于余数p,分析可以得到当在d[n-i]处+1,最终到b会+2^i,因此可对余数p的二进制数处理然后在对于的d[i]上+1即可
Code:
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MAX_S=55;
int n,T;
LL d[MAX_S],m;
int main()
{
ios::sync_with_stdio(false);
cin>>T;
LL a,b,p;
while(T--){
cin>>a>>b>>m;
if(a==b){
cout<<1<<" "<<a<<endl;
continue;
}
n=0; p=1;
while(n<50&&p*(a+m)<b){
++n; p*=2;
}
LL l=1,r=m,h;
while(l<=r){
h=(l+r)/2;
if(p*(a+h)<=b) l=h+1;
else r=h-1;
}
if(!r){
cout<<-1<<endl;
continue;
}
p=b-p*(a+r);
for(int i=1;i<=n;++i)
d[i]=r;
r=n;
while(p){
if(p&1) ++d[r];
p>>=1; --r;
}
p=d[0]=a; d[n+1]=b;
for(int i=1;i<=n;p+=d[i],++i)
d[i]+=p;
cout<<n+2<<" ";
for(int i=0;i<=n;++i)
cout<<d[i]<<" ";
cout<<d[n+1]<<endl;
}
return 0;
}