题意
题解
dp定义真的神,
直接的想法是$f[x][maxn]$为第$x$个操作,状态$maxn$,$maxn$1<<200,好像没有暴力分高
实际上我们可以这样定义$f[x][maxn][len][0\1]$表示后八位$maxn$,第九位0\1,第九位之后连续长度为$j$概率
为什么这样定义
实际上质因数分解后2的次数就是后面0的个数
+1会破坏已有的0,操作数最多只有200个全部+1后八位已经足够
最多只会影响到后九位一次
考虑一种极限情况
111111111111111
现在在最后一位加一会进位
1000000000000000,再怎么+1都不会再影响到九位之后了
转移比较简单具体看代码
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 ll x,n,m,xx,opt,maxn,cnt; 5 double p,ans=0; 6 double f[210][288][310][2]; 7 ll cal(ll now){ 8 ll cnt=0; 9 while(now%2==0) cnt++,now/=2; 10 return cnt; 11 } 12 int main(){ 13 // freopen("cnm.xlsx","w",stdout); 14 scanf("%lld%lld%lf",&x,&n,&p); 15 p/=100; 16 xx=x; 17 xx>>=8; 18 opt=xx&1; 19 maxn=(1<<8)-1; 20 for(;xx&&((xx&1)==opt);xx>>=1) 21 cnt++; 22 if(cnt==0) cnt++;// 23 m=cnt+n; 24 f[0][x&maxn][cnt][opt]=1; 25 // printf("%lld\n",m); 26 for(ll i=1;i<=n;i++) 27 for(ll pre=0;pre<=maxn;pre++) 28 for(ll j=1;j<=m;j++) 29 for(ll t=0;t<=1;t++) 30 if(f[i-1][pre][j][t]){ 31 ll now,tt,jj; 32 now=pre+1; 33 if(now==(1<<8)){ 34 now=0;tt=t^1; 35 if(t==1) jj=j; 36 else jj=1; 37 } 38 else jj=j,tt=t; 39 f[i][now][jj][tt]+=f[i-1][pre][j][t]*(1-p); 40 now=pre<<1; 41 if(((now>>8)&1)==t) tt=t,jj=j+1; 42 else tt=t^1,jj=1; 43 now=now&maxn; 44 f[i][now][jj][tt]+=f[i-1][pre][j][t]*p; 45 } 46 for(ll now=1;now<=maxn;now++)// 47 for(ll j=1;j<=m;j++) 48 for(ll t=0;t<=1;t++) 49 if(f[n][now][j][t]) 50 ans+=f[n][now][j][t]*cal(now); 51 //,printf("f[%lld][%lld][%lld][%lld]=%lf\n",n,now,j,t,f[n][now][j][t]); 52 // printf("%.13lf\n",ans); 53 for(ll j=1;j<=m;j++){ 54 ans+=f[n][0][j][0]*(j+8)+f[n][0][j][1]*8; 55 // printf("f[%lld][0][%lld][0]=%lf f[%lld][0][%lld][1]=%lf\n",n,j,f[n][0][j][0],n,j,f[n][0][j][1]); 56 } 57 printf("%.13lf\n",ans); 58 }