a^b的前n位数

  假设我们现在需要知道 ab  的后 n 位数或前 n 位数,简单直观的做法就是求出 ab  的值,然后在分别取前 n位或后 n位,不过在 a,b很大的情况下显然是无法存储的。所以,直接求是不可能的了。

  让我们先来看看后 n 位如何求?因为我们只要后 n 位,那么我们都知道把 ab  的值模上一个10n 就是所求。根据求模的性质:ab % n = (a%n)b % n;然后用快速幂跑一遍即可。

  

 1 int QuickPow (__int64 a, __int64 b)
 2 {
 3     __int64 r = 1;
 4     while (b)
 5     {
 6         if (b&1)
 7             r = (r*a) % (__int64)pow(10.0, n*1.0);
 8         a = ( a*a) % (__int64)pow(10.0, n*1.0);
 9         b >>= 1;
10     }
11     return r;
12 }

  关键是前 n 如何求?我们假设 ab = c。再设 log10 (c) = d。另 Int 为 d 的整数部分,k 为小数部分,那么 10Int = 100......0(共Int个0),不难发现,除了第一位是1外其余均为0,也就说,10k 最终将直接影响最左边的 N 位数。将这个结果乘以1,就是前1位的答案,乘以10,就是前2位的答案。。。类推!

  后来发现任何一个数字 n 都可以表示成10(a+b) 。其中 a整数,b为小数。例如

    n=87455时,a=4,b=0.941784644.

    有规律.10a =10000.10b =8.7455.

  所以n的左边数起第一位数字。就是10b 的第一位有效数字,第二数字,是10^b的第二位有效数字。。。。以次类推

以hdu 1060为例:

#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;

int main()
{
    int t;
    __int64 n;
    __int64 Int;
    double a, d;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%I64d", &n);
        a = n*log10(n*1.0);
        Int = (__int64)a;
        d = a - Int;
        printf("%I64d\n", (__int64)pow(10, d));
    }
    return 0;
}
时间: 2024-10-05 10:25:30

a^b的前n位数的相关文章

light_oj 1282 求n^k的前几位数和后几位数

light_oj 1282 求n^k的前几位数和后几位数 E - Leading and Trailing Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice LightOJ 1282 Description You are given two integers: n and k, your task is to find the most signif

字符串截取前几位数,截取小数点之前的数字

1,截取字符串前i个字符 str=str.substring(0,i); 2,去掉字符串的前i个字符str=str.substring(i); 将字符串从索引号为2开始截取, var sb = "bbbdsajjds"; sb.substring(2); //bdsajjds 从索引号2开始到索引好4结束(并且不包含索引4截取在内,也就是说实际截取的是2和3号字符): var sb = "bbbdsajjds"; sb.substring(2, 4); //bd 方

Python给数字前固定位数加零

python中有一个zfill方法用来给字符串前面补0,非常有用 1 n = "123" 2 s = n.zfill(5) 3 assert s == "00123" zfill()也可以给负数补0 1 n = "-123" 2 s = n.zfill(5) 3 assert s == "-0123" 对于纯数字,我们也可以通过格式化的方式来补0 n = 123 s = "%05d" % n assert

用递归和迭代写斐波那契数列,前n列的和

首先注意: 方法不调用不执行,调用才执行,并且把值返回到方法的调用处!! public class Fei_Bo_Na_Qi{    public static void main(String[] args){        int m = 100;        System.out.println( "斐波那契数列的第 "+m+" 位数为: "+m1(m) );//  在输出的时候调用函数    }    public static int  m1(int i

JAVA浮点数保留位数

方式一: BigDecimal.setScale用于格式化小数点 setScale(1)表示保留以为小数,默认用四舍五入方式 setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3 setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4 setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4 setScaler(1,BigDecimal.ROUND_HALF_

java.math.BigDecimal保留两位小数,保留小数,精确位数

http://blog.csdn.net/yuhua3272004/article/details/3075436 使用java.math.BigDecimal工具类实现 java保留两位小数问题: 方式一(四舍五入形式保留两位小数,注意模式ROUND_HALF_UP): 四舍五入   double   f   =   111231.5585;   BigDecimal   b   =   new   BigDecimal(f);   double   f1   =   b.setScale(2

UVA 11029 Leading and Trailing(大数n^k的前x位高精度问题)(好题)

Problem C Leading and Trailing Time limit: 2 seconds   Apart from the novice programmers, all others know that you can't exactly represent numbers raised to some high power. For example, the C function pow(125456, 455) can be represented in double da

[hdu 1568] Fibonacci数列前4位

2007年到来了.经过2006年一年的修炼,数学神童zouyu终于把0到100000000的Fibonacci数列(f[0]=0,f[1]=1;f[i] = f[i-1]+f[i-2](i>=2))的值全部给背了下来.接下来,CodeStar决定要考考他,于是每问他一个数字,他就要把答案说出来,不过有的数字太长了.所以规定超过4位的只要说出前4位就可以了,可是CodeStar自己又记不住.于是他决定编写一个程序来测验zouyu说的是否正确. Input 输入若干数字n(0 <= n <=

HDU 3555 Bomb (数位DP)

数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快.数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来. 简介: 顾名思义,所谓的数位DP就是按照数字的个,十,百,千--位数进行的DP.数位DP的题目有着非常明显的性质: 询问[l,r]的区间内,有多少的数字满足某个性质 做法根据前缀和的思想,求出[0,l-1]和[0,r]中满足性质的数的个数,然后相减即可. 算法核心: 关于数位DP,貌似写法还是