CF1453D题解

VP 的时候发现的一道数学题(

在思考这个问题之前,先让我们思考一件事:走到距离上一个存档点 n 的位置的期望是多少?(假设这个值为 f[n]

先思考 f[1] 是多少,很明显是:

S=i=0i×2i

手拆一下:

21S=i=1(i1)×2i

相减:

21S=i=12i

很容易得到 21S=1,也就是 f[1]=2 当然你也可以通过观察样例来得到这个结论

来思考 f[n],考虑从 f[n1] 递推过来。枚举失败的次数:

f[n]=k=0((k+1)×f[n1]+(k+1))×2k1

f[n]=(f[n1]+1)k=1k×2k

于是有 f[n]=(f[n1]+1)×2。手玩一下即可发现 f[n]=2n+22

因为期望具有线性性,(E(a+b)=E(a)+E(b))于是问题就变成了了如何用若干个 f 凑出 k

变形一下,f[n]=2(2n+11),说明 n 为奇数时一定不行。

于是我们枚举最大的 f,枚举到一个就让 k 减去 f,然后当做当前的 k 接着做。

#include<cstdio>
typedef long long ll;
ll k,f[61];int len,ans[2005];
signed main(){
	int T,i,j;ll k;f[0]=2;scanf("%d",&T);
	for(int i(1);i<=60;++i)f[i]=f[i-1]+1<<1;
	while(T--){
		scanf("%lld",&k);len=0;
		if(k&1){
			printf("-1\n");continue;
		}
		for(i=60;i>=0;--i){
			while(k>=f[i]){
				ans[++len]=1;
				for(j=1;j<=i;++j)ans[++len]=0;k-=f[i];
			}
		}
		printf("%d\n",len);
		for(i=1;i<=len;++i)printf("%d ",ans[i]);printf("\n");
	}
}

本文作者:Prean

本文链接:https://www.cnblogs.com/lmpp/p/15788262.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Prean  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
var canShowAdsense=function(){return !!0};
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起