一、题目描述:
你有一个骰子,数字 1~6 可以被等概率扔到。
初始时有一个数 $ans=1$。
当扔到数字 $x$ 时,$ans=ans \times x$。
给你一个数字 $n$ ,求 $ans$ 能等于 $n$ 的概率。
$n<=1e18$。答案对 $998244353$ 取模。
二、解题思路:
当扔到 $1$ 时,相当于没扔,所以可以视为 5 个数
求出 $n$ 的质因数 $2$,$3$,$5$ 的个数,设有 $ans_2$ 个$2$,$ans_3$ 个$3$,$ans_5$ 个$5$。
一个 $6$ 相当于一个 $2$ 和一个 $3$ 相乘,一个 $4$ 相当于两个 $2$ 相乘。
枚举 $4$ 的数量,再枚举 $6$ 的数量,再套组合数板子:多重集的排列数量。
最后求和。需要用到逆元,阶乘。时间复杂度O($log^3n$),可以通过。
三、完整代码:
1 #include<iostream> 2 #define ll long long 3 #define mod 998244353 4 using namespace std; 5 ll n,t2=1,rans,jc[100]; 6 ll ans2,ans3,ans5; 7 ll qsm(ll base,ll p) 8 { 9 ll ans=1; 10 while(p) 11 { 12 if(p&1) ans*=base,ans%=mod; 13 base*=base,base%=mod,p>>=1; 14 } 15 return ans; 16 } 17 int main() 18 { 19 cin>>n;jc[0]=1; 20 while(n&&n%2==0) 21 ans2++,n/=2; 22 while(n&&n%3==0) 23 ans3++,n/=3; 24 while(n&&n%5==0) 25 ans5++,n/=5; 26 if(n!=1) 27 { 28 cout<<0<<'\n'; 29 return 0; 30 } 31 for(ll i=1;i<=70;i++) 32 jc[i]=jc[i-1]*i%mod; 33 for(ll i=0;i<=min(ans2,ans3);i++) 34 for(int j=0;j*2<=ans2-i;j++) 35 { 36 ll t=ans2+ans3+ans5-i-j; 37 t2=jc[t]*qsm(qsm(5,t),mod-2)%mod; 38 t2*=qsm(jc[i],mod-2),t2%=mod; 39 t2*=qsm(jc[j],mod-2),t2%=mod; 40 t2*=qsm(jc[ans5],mod-2),t2%=mod; 41 t2*=qsm(jc[ans3-i],mod-2),t2%=mod; 42 t2*=qsm(jc[ans2-i-j*2],mod-2),t2%=mod; 43 44 rans+=t2,rans%=mod; 45 } 46 cout<<rans<<'\n'; 47 return 0; 48 }
四、写题心得:
很好的一道题,对我来说有难度。这次是完全自己想出来的,很高兴,可惜是在比赛后十分钟写出来的 qwq!不过还是加油吧!拜拜!
标签:题解,ll,while,base,&&,ans,abs300,mod From: https://www.cnblogs.com/yhy-trh/p/17364576.html