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; }