2019牛客暑期多校训练营(第二场)
参考资料:
[1]:官方题解(提取码:ar7y)
[2]:标程(提取码:3qb2)
A.Eddy Walker(概率+打表找规律)
•题意
有一个圆,圆上有 n 个点,编号为 0~n-1;
初始,Eddy 处于 0 位置,每次他独立地均匀随机选择是向前(0+1)还是向后(0-1 = n-1)走;
现给你 n,m ,让你求 Eddy 在走 n 步后停留在 m 处的概率;
最终结果输出前缀积;
•题解
在补这道题前,补了补概率论的相关概念;
1.频率定义
若在相同的条件下进行的 n 次试验中,事件 A 发生了 m 次,则称比值 m / n 为事件 A 发生的频率;
2.概率的统计定义
在相同条件下进行大量重复试验,当试验次数充分大时,事件 A 的频率将在某个常数 p 附近摆动,
这个常数 p 称为事件 A 的概率,记为 P(A);有了这些概念后,找了几篇博文看,发现,要么是达标找规律,要么就是直接写结论,没有严格的数学证明;
哎,本蒟蒻太菜,并不擅长概率论方面的题,暂且补补打表找规律的;
打表找规律
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mem(a,b) memset(a,b,sizeof(a)) 4 const int maxn=100; 5 6 int n; 7 bool vis[maxn]; 8 int k[maxn]; 9 10 int main() 11 { 12 srand((unsigned int)(time(NULL))); 13 14 scanf("%d",&n);///n最好不要太大,不然,不能再有限的时间内跑出结果 15 for(int i=1;i <= 100000;i++) 16 { 17 mem(vis,false); 18 vis[0]=true; 19 20 int cur=0; 21 int t=1; 22 23 while(t < n) 24 { 25 int x=rand()%2 ? 1:-1;///向前或向后走 26 cur=(cur+x+n)%n; 27 28 if(!vis[cur]) 29 { 30 vis[cur]=true; 31 t++; 32 } 33 } 34 k[cur]++; 35 } 36 for(int i=1;i < n;i++) 37 printf("%d ",k[i]); 38 printf(" "); 39 40 return 0; 41 }
当输入的 n = 10 时,大概可以看出除 0 外,其他位置的概率为 1 / (n-1);
0 单独处理;
•Code
View Code
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int MOD=1e9+7; 5 6 ll qPow(ll a,ll b) 7 { 8 ll ans=1; 9 a %= MOD; 10 11 while(b) 12 { 13 if(b&1) 14 ans=ans*a%MOD; 15 16 a=a*a%MOD; 17 b >>= 1; 18 } 19 return ans; 20 } 21 ll Inv(ll a)///返回 a 的逆元 22 { 23 return qPow(a,MOD-2)%MOD; 24 } 25 int main() 26 { 27 int T; 28 scanf("%d",&T); 29 30 ll ans=1; 31 while(T--) 32 { 33 int n,m; 34 scanf("%d%d",&n,&m); 35 ll cur; 36 if(m == 0) 37 { 38 if(n != 1) 39 cur=0; 40 else 41 cur=1; 42 } 43 else 44 cur=Inv(n-1);///cur = {1/(n-1)}%MOD; 45 46 ans=ans*cur%MOD; 47 48 printf("%lld ",ans); 49 } 50 return 0; 51 }