作者:nora抹抹茶I | 来源:互联网 | 2023-10-12 18:47
题目描述 立华奏在学习初中数学的时候遇到了这样一道大水题:
“设箱子内有 n 个球,其中给 m 个球打上标记,设一次摸球摸到每一个球的概率均等,求一次摸球摸到打标记的球的概率。”
“emmm…语言入门题。”
但是她改了一下询问方式:设最终的答案为 p,请输出 p 小数点后 K1 到 K2 位的所有数字(若不足则用 0 补齐)。
输入格式 第一行一个整数 T,表示有 T 组数据。
接下来每行包含四个整数 m,n,K1,K2,意义如「题目描述」所示。
输出格式 输出 T 行,每行输出 K2 - K1 + 1 个数,表示答案。
注意同行的数字中间不需要用空格隔开。
输入样例 5 2 3 2 3 1 7 1 7 2 5 1 3 12345 54321 3 10 12345 54321 100000 100010
输出样例 66 1428571 400 72601756 78428232175
说明 对于 100% 的数据,1≤m≤n≤1091 ≤ m ≤ n ≤ 10^9 1 ≤ m ≤ n ≤ 1 0 9 ,1≤K1≤K2≤1091 ≤ K1 ≤ K2 ≤ 10^9 1 ≤ K 1 ≤ K 2 ≤ 1 0 9 ,0≤K2−K1≤1050 ≤ K2 - K1 ≤ 10^5 0 ≤ K 2 − K 1 ≤ 1 0 5 ,T≤20T ≤ 20 T ≤ 2 0 。
对于求概率,直接用 m/nm/n m / n 即可。
若 m/nm/n m / n 结果为有限小数,设小数位数为 xx x ,m/n∗10xm/n*10^x m / n ∗ 1 0 x 即为 m/nm/n m / n 去掉小数点后的数字,(m∗10x/n)mod10(m*10^x/n) mod 10 ( m ∗ 1 0 x / n ) m o d 1 0 为去掉小数点后的数字的最后一位,即原数的小数点后第 xx x 位。
进一步得出,求小数点后第 ii i 位数字,即为 int(m∗10i/n)mod10int(m*10^i/n)mod 10 i n t ( m ∗ 1 0 i / n ) m o d 1 0 。
其中 10i10^i 1 0 i 可直接用快速幂求出。
但是对于 int(m∗10i/n)mod10int(m*10^i/n)mod 10 i n t ( m ∗ 1 0 i / n ) m o d 1 0 而言,其中 m∗10im*10^i m ∗ 1 0 i 容纳不了太多的位数,怎么办呢?
这时可以想到: (a/n)mod10(a/n)mod 10 ( a / n ) m o d 1 0 若 a>10na>10n a > 1 0 n ,则:
原式 =((a−10n+10n)/n)mod10=((a-10n+10n)/n)mod10 = ( ( a − 1 0 n + 1 0 n ) / n ) m o d 1 0 =((a−10n)/n+10n/n)mod10=((a-10n)/n+10n/n)mod10 = ( ( a − 1 0 n ) / n + 1 0 n / n ) m o d 1 0 =((a−10n)/n+10)mod10=((a-10n)/n+10)mod10 = ( ( a − 1 0 n ) / n + 1 0 ) m o d 1 0 =((a−10n)/n)mod10=((a-10n)/n)mod10 = ( ( a − 1 0 n ) / n ) m o d 1 0 进一步,可以想到 aa a 和 amod10amod10 a m o d 1 0 的结果是相同。
把此式代入 (m∗10i/n)mod10(m*10^i/n)mod 10 ( m ∗ 1 0 i / n ) m o d 1 0 ,有: (m∗10i/n)mod10(m*10^i/n)mod 10 ( m ∗ 1 0 i / n ) m o d 1 0 =int(10i∗((m−10n+10n)/n))mod10=int(10^i*((m-10n+10n)/n))mod 10 = i n t ( 1 0 i ∗ ( ( m − 1 0 n + 1 0 n ) / n ) ) m o d 1 0 =int(10i∗((m−10n)/n+10n/n))mod10=int(10^i*((m-10n)/n+10n/n))mod 10 = i n t ( 1 0 i ∗ ( ( m − 1 0 n ) / n + 1 0 n / n ) ) m o d 1 0 =int(10i∗((m−10n)/n+10))mod10=int(10^i*((m-10n)/n+10))mod 10 = i n t ( 1 0 i ∗ ( ( m − 1 0 n ) / n + 1 0 ) ) m o d 1 0 =int(10i∗(m−10n)/n+10i∗10)mod10=int(10^i*(m-10n)/n+10^i*10)mod 10 = i n t ( 1 0 i ∗ ( m − 1 0 n ) / n + 1 0 i ∗ 1 0 ) m o d 1 0 =int(10i∗(m−10n)/n)mod10=int(10^i*(m-10n)/n)mod 10 = i n t ( 1 0 i ∗ ( m − 1 0 n ) / n ) m o d 1 0 =int(10i∗(mmod10n)/n)mod10=int(10^i*(mmod10n)/n)mod 10 = i n t ( 1 0 i ∗ ( m m o d 1 0 n ) / n ) m o d 1 0 =int(((10i∗(mmod10n))mod10n)/n)mod10=int(((10^i*(mmod10n))mod10n)/n)mod 10 = i n t ( ( ( 1 0 i ∗ ( m m o d 1 0 n ) ) m o d 1 0 n ) / n ) m o d 1 0
便变成了快速幂求 mod10nmod10n m o d 1 0 n 的余数了。
# include # include using namespace std; long long t, n, m, k1, k2; long long pow ( long long i) { long long ans&#61; m% ( 10 * n) , a&#61; 10 ; while ( i) { if ( i& 1 ) ans&#61; ( ans* a) % ( 10 * n) ; a&#61; ( a* a) % ( 10 * n) ; i>>&#61; 1 ; } return ans; } int main ( ) { cin>> t; while ( t-- ) { cin>> m>> n>> k1>> k2; for ( long long i&#61; k1; i<&#61; k2; i&#43;&#43; ) cout<< ( pow ( i) / n) % 10 ; cout<< &#39;\n&#39; ; } return 0 ; }