2017南宁现场赛E 存档
现场时间不够,没加记忆化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)); } }