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
題意如標題
後三位好說,快速冪取個模
前三位我們可以這樣:直接作爲正整數n^k來取很難,因爲這個數會很大並且無法捨去後面的數字來做優化,我們可以轉化爲小數:
log10(n^k)=k*log10(n),然後又因爲n^k=z*10^x,即有log10(n^k)=log10(z)+x,並且在n^k=z*10^x中,x(即10^x)只貢獻了該整數的位數,真正的前三位
都被實數z貢獻了。
所以有10^(log10(z))的個位和小數點後兩位即是n^k的前三位(因爲是用科學計數法的,所以z肯定有且只有一個整數位,即只有個位,其餘都是小數位)
所以根據式子log10(z)=(double)k*log10(n)-(LL)k*log10(n)即可
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn=2e5+3;
LL n,k;
LL quick(LL x,LL a)
{
LL res=1,MOD=1000;
while(a)
{
if(a&1)res=x*res%MOD;
x=x*x%MOD;
a>>=1;
}
return res%MOD;
}
int main()
{
int T;
scanf("%d",&T);
int cas=0;
while(T--)
{
scanf("%lld%lld",&n,&k);
LL a1,a2=quick(n,k),z=k*log10(n);
double x=k*log10(n)-(double)z;
x=pow(10,x)*100;//printf("z=%lld x=%f\n",z,x);
a1=x;
printf("Case %d: %lld ",++cas,a1);
if(a2>=100)printf("%lld\n",a2);
else if(a2>=10)printf("0%lld\n",a2);
else printf("00%lld\n",a2);
}
return 0;
}