Bzoj3652 大新闻

Time Limit: 10 Sec  Memory Limit: 512 MBSec  Special Judge
Submit: 215  Solved: 112

Description

Input

Output

Sample Input

3 0.5

Sample Output

2.000000

HINT

 


1<=N<=10^18

 

Source

 

加密和不加密各自是独立问题

后者是炒鸡麻烦的数位DP

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #define LL long long
 6 using namespace std;
 7 const int mxn=100010;
 8 LL n;
 9 LL b[70];
10 double p;
11 int len;
12 double pw(){//加密 
13     double res=0;
14     for(int i=0;i<len;i++){
15         double L=(n/(1LL<<(i+1)))*(double)(1LL<<i);
16         //高位取遍所有情况,当前位为0,低位无限制 
17         double R=(max(0LL,n%(1LL<<(i+1))-(1LL<<i)));
18         //高位为极限,当前位为1,低位不超限 
19         L=(L+R)/n;
20         res+=L*(1-L)*2*(1LL<<i);
21         //取对立情况使得该位异或和为1的期望*贡献  x,y交换是另一种情况,所以*2 
22     }
23     return res;
24 }
25 double f[200];
26 double npw(){//未加密
27     n--;//右侧开区间 
28     double res=0;
29     if(n&1)f[0]=2;else f[0]=1;
30     f[0]/=(n+1);
31     LL m=n;
32     int i,j;
33     for(i=1;i<len-1;i++){
34         if((n>>i)&1)f[i]=f[i-1]+(double)b[i]/(n+1)*b[i]*2+(double)(b[i]-1)*1.0/(n+1)*b[i];
35         else f[i]=f[i-1]*2+(b[i])/(double)(n+1)*(b[i]);
36     }
37     for(int i=len-1;i>=0;i--){
38         if((n>>i)&1){//x可以取1 
39             if((m>>i)&1){//y可以取1 
40                 res+=(b[i+1]-1)*(double)(m+1-(b[i]))/(n+1);
41                 m=(b[i])-1;
42             }
43             res+=b[i]*(double)(m+1)/(n+1);
44         }
45         else{
46             if((m>>i)&1){
47                 res+=(b[i])*(double)(m+1-(b[i]))/(n+1);
48                 m^=(b[i]);
49                 res+=i-1>=0?f[i-1]:0;
50             }
51         }
52     }
53     n++;
54     return res;
55 }
56 int main(){
57     int i,j;
58     scanf("%lld%lf",&n,&p);
59     len=1;
60     while((1LL<<len)<=n)++len;
61     for(i=0;i<=len;i++)b[i]=1LL<<i;
62     printf("%.8f\n",npw()*p+pw()*(1-p));
63     return 0;
64 }

 

posted @ 2017-02-19 15:21  SilverNebula  阅读(356)  评论(0编辑  收藏  举报
AmazingCounters.com