Leading and Trailing

Leading and Trailing
题面
Leading and Trailing
题意
输出nkn^{k}的前3位数与后3位数,如果位数不够补0。
分析
nkn^{k}的后三位,相对而言,是容易求出的。我们可以直接用快速幂取模的方法,对nkn^{k}mod1000,即可以得到我们所要求的答案。但是这题的难点主要是怎么求前三位,接下来我来重点讲一下怎么推导求前三位的方法。
推导
nkn^{k}=10lgnk10^{lgn^{k}}=10klgn10^{k*lgn},设klgn=a+b(ab)k*lgn=a+b(其中a是整数,b是小数)
那么nkn^{k}=10lgnk10^{lgn^{k}}=10klgn=10a+b=10a10b10^{k*lgn}=10^{a+b}=10^{a}*10^{b}
我们可以知道10a10^{a}并不会改变前3位数的大小,仅仅改变位置,但是10b10^{b}中b是小数,所以会改变前3位数的大小
1=100<=10b<101=10(0<=b<1)1=10^{0}<=10^{b}<10^{1}=10 (0<=b<1),这下问题就转化为如何求b?
如何求b呢
modf()函数
利用这个函数就可以把klgnk*lgn的b算出来,那么我们还要分析一下klgnk*lgn是否会出现数据范围爆出的问题,double可控制的是16位,而klgn<1e9k*lgn<1e9.所以可实现。
AC代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
ll n,k,fir,res;
double x,y;
ll quick_mod(ll a,ll b,ll p){
	ll num=a,sum=1;
while(b){
	if(b&1){
		sum=sum*num%p;
	}
	num=num*num%p;
	b>>=1;
}
return sum;
}///a^b mod p*/
int main(){
	int t,num=1;
	cin>>t;
	while(t--){
	        scanf("%lld%lld",&n,&k);
		res=quick_mod(n,k,1000);///res表示后三位
		y=modf((double)(k*log10(n)),&x);
		fir=pow(10,y)*100;
		printf("Case %d: %03lld %03lld\n",num++,fir,res);
	}
	return 0;
}