uva 11029 Leading and Trailing

数论题:幂取模

给出a和n,求a^n的前3位和后3位

关于求后3位,就是一个二分并且模1000即可,至于怎么求前3位,需要一些数学分析

我们来看一大数n

n可以写成n=10^b,这个a是个小数
所以b=i+d,i是整数部分,d是数部分
则n=10^(i+d)=10^i * 10^d
这里很重要,10^i其实有什么用?i是整数,所以10^i一定是1000…………000,然后*10^d,d是一个小于1的小数(别忘了是b的小数部分)
所以决定n这个大数会出现什么数字的,是10^d,10^i只是给10^d起到往后移动小数点的作用
所以我们要知道10^d
另外我们知道0<=d<1,所以 10^0 <= 10^d < 10^1   即1<=10^d<10

这样只需要10^d*100然后取整数部分,就能得到一个3位整数,这3个数字正是我们要的答案

 

a=10^k , a^n=(10^k)^n=10^k*n=10^i * 10^d    ,  这里i是k*n的整数部分,d是k*n的小数部分

要得到k就使用库函数fmod即可    d=fmod(k*n , 1) , 返回k*n/1的余数,也就是小数部分

另外k=log10(a) , 写在一起就是   d=fmod( log10(a)*n , 1) 

然后就是求  100*10^d=10^(d+2) 

 

//幂取模,保存后3位和前3位
#include <cstdio>
#include <cmath>
#define M 1000

int pow_mod(int a , int n)
{
    if(n==1)   return a%M;
    int x=pow_mod(a,n/2);
    long long ans=(long long)x*x%M;
    if(n&1)   ans=ans*a%M;
    return (int)ans;
}

int main()
{
    int T,a,n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&a,&n);
        int left,right;
        left=(int)pow( 10.0 , 2 + fmod(n*log10(1.*a) , 1) );
        right=pow_mod(a,n);
        printf("%d...%03d\n",left,right);
    }
    return 0;
}

 

posted @ 2013-02-03 18:29  Titanium  阅读(401)  评论(0编辑  收藏  举报