题目
思路
根据题意,我们要保证不能亏灵石,因此方案首先可以确定为1,1,2,4,8,16……2^(n-2),如果灵石不足以确定这个方案,说明没有方案,输出-1,如果灵石有剩余,因为要满足前x-1轮一样时,第x轮获胜得到的总灵石最多,所以需要从第一轮向右遍历,假设当前处在第i轮,我们要让剩余的灵石尽可能在第i轮押下最多并使得后面第i+1轮到第n轮都添加相应的灵石来维护必定不会亏灵石的条件。对于具体的添加,我们知道当i轮添加了j个灵石后,第i+1轮也要添加j个灵石,第i+2轮则要添加j*2个灵石,第i+3轮要添加j*4个灵石……。所以问题就解决了。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
long long arr[maxn];
long long add[maxn];
long long temp[maxn];
int main(){
long long n,m;
cin>>n>>m;
if(n==1){
cout<<m;
return 0;
}
else if(n>=m){
cout<<"-1";
return 0;
}
arr[0]=1;arr[1]=1;m-=2;
long long sum=2;
for(int i=2;i<n;i++){
arr[i]+=sum;
sum+=sum;
m-=arr[i];
if(m<0){
cout<<"-1";
return 0;
}
//cout<<arr[i]<<" ";
}
//cout<<endl;
for(int i=0;i<n;i++,sum/=2){
if(m/sum>0){
add[i]=m/sum;
m%=sum;
}
//cout<<add[i]<<" ";
//cout<<m<<endl;
}
//cout<<endl;
for(int i=0;i<n;i++)temp[i]=add[i];
for(int i=1;i<n;i++)temp[i]+=temp[i-1]*2-add[i-1];
//for(int i=n-1;i>0;i--)add[i]=temp[i]-add[i-1];
for(int i=0;i<n;i++)cout<<arr[i]+temp[i]<<" ";
}