Leading and Trailing
Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu

Submit Status
Description

You are given two integers: n and k, your task is to find the most significant three digits, and least significant three digits of nk.

Input

Input starts with an integer T (≤ 1000), denoting the number of test cases.

Each case starts with a line containing two integers: n (2 ≤ n < 231) and k (1 ≤ k ≤ 107).

Output

For each case, print the case number and the three leading digits (most significant) and three trailing digits (least significant). You can assume that the input is given such that nk contains at least six digits.

Sample Input

5

123456 1

123456 2

2 31

2 32

29 8751919

Sample Output

Case 1: 123 456

Case 2: 152 936

Case 3: 214 648

Case 4: 429 296

Case 5: 665 669

题意: 求解a^b 的前三位和后三位

解法: 对于后三位,快速幂取模1000即可;

前三位要具体进行分析。

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)

代码:

#include <stdio.h>  
#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <ctype.h>
#include <time.h>
#include <queue>
#include <iterator>

using namespace std;

long long quickpow(long long m, long long n, long long k)//快速幂
{
long long b = 1;
while (n > 0)
{
if (n & 1)
b = (b*m) % k;
n = n >> 1;
m = (m*m) % k;
}
return b;
}

int t;
long long a, b , ans1, ans2;

int main()
{
int cases = 1;
scanf("%d",&t);
while (t--)
{
scanf("%lld %lld",&a,&b);
long long x = a % 1000;
ans1 = (int)pow(10, 2 + fmod (b * log10(a*1.0) ,1 ));//求前三位
ans2 = quickpow(x,b,1000);
printf("Case %d: %03lld %03lld\n", cases++, ans1, ans2);
}
return 0;
}