现场时间不够,没加记忆化T了,滚cu
当时还写错了mx1,mx2的关系。。。
出场喜闻乐见有人加记忆化传参递归过。。不过似乎是用的map?
这份代码未必是正解,等到放上hdu交上去试试吧。。欢迎hack!
#include<bits/stdc++.h>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<iostream>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<iomanip>
using namespace std;
#define ll long long
#define pb push_back
#define FOR(a) for(int i=1;i<=a;i++)
const int inf=0x3f3f3f3f;
const int maxn=2e5+5e4+9;
const int mod=985003;
ll r,k;double p;
double vis[2049][2049];
double work(ll qiang,ll ruo){
if(qiang==0 && ruo==0)return 1;
if(qiang<=2048 && ruo<=2048 && vis[qiang][ruo]){
return vis[qiang][ruo];
}
ll hq=qiang>>1,hr=ruo>>1;
if(ruo%2==1){
vis[qiang][ruo]=p*work(hq,hr);
return vis[qiang][ruo];
}else if(qiang%2==1){
if(ruo){
double mx1=p*work(hq+1,(ruo-2)/2);
double mx2=(1-p)*work(hq,hr);
vis[qiang][ruo]=p*(mx1+mx2);
return vis[qiang][ruo];
}else{
vis[qiang][ruo]=(1-p)*work(hq,0);
return vis[qiang][ruo];
}
}
}
int main(){
int T;scanf("%d",&T);
while(T--){
memset(vis,0,sizeof vis);
scanf("%lld%lld%lf",&r,&k,&p); //进行r轮,排名k
ll num=1ll<<r;
ll qiang=k-1,ruo=num-k;
if(p<0.5)swap(qiang,ruo);
printf("%.6lf\n",work(qiang,ruo));
}
}