题目描述
众所周知,aba^bab表示a的b次幂。例如:232^323=2∗2∗22*2*22∗2∗2=888。
一天,某只肥皂很无聊,于是在纸上写了形如a^b的式子玩。FL见到了,过来一起玩。突然,FL脑洞一开:我给你普及一个符号“^^”,叫做超级幂。
a^^b表示a^(a^(a^(a^a^(...)))),共b个a。
例如2^^3=2^(2^2)=2^4=16。那么你知道a^^b的个位数是多少么?
肥皂表示一脸懵逼,于是一旁看热闹的YDL出现了,
随手写了一个式子:(a1^^b1)*(a2^^b2)*(a3^^b3)........(an^^bn),保证ai的个位数不等于2或4或8。
说,请求出这个式子的个位数。
肥皂和FL两脸懵逼。现在FL只好想你求助了。
注意:a^^0=1,表示有0个a, 例如: 3^^0=1
输入
第一行一个T,表示有T组数据。
接下来T∗2T*2T∗2行。
第j∗2j*2j∗2行一个整数nnn。
第j∗2+1j*2+1j∗2+1行,n对整数aia_iai,bib_ibi,用空格隔开。
输出
输出共TTT行。
对于每个T,输出一个整数,表示a1^^b1*a2^^b2*a3^^b3........an^^bn的个位数是多少。
数据范围限制
对于10%的数据,满足T=1,1<=n,ai<=5,0<=bi<=3T=1,1<=n,a_i<=5,0<=b_i<=3T=1,1<=n,ai<=5,0<=bi<=3。
对于30%的数据,满足1<=T<=5,1<=n,ai<=100,0<=bi<=51<=T<=5,1<=n,a_i<=100,0<=b_i<=51<=T<=5,1<=n,ai<=100,0<=bi<=5。
对于50%的数据,满足1<=T<=20,1<=n,ai<=5000,0<=bi<=50001<=T<=20,1<=n,a_i<=5000,0<=b_i<=50001<=T<=20,1<=n,ai<=5000,0<=bi<=5000
对于100%的数据,满足1<=T<=100,1<=n<=5000,1<=ai<=50000,0<=bi<=1081<=T<=100,1<=n<=5000,1<=a_i<=50000,0<=b_i<=10^81<=T<=100,1<=n<=5000,1<=ai<=50000,0<=bi<=108
aia_iai的个位数不等于2或4或8。
题解
我们可以分类讨论(好像也可以找规律)。
对于各组数据之间是独立的,所以我们先只考虑(ai^^bi) mod 10
因为题目只要求输出个位,所以可以让cicici===aia_iai mod101010
然后有0<=ci<=90<=ci<=90<=ci<=9,cicici是整数。
若ci=1ci=1ci=1,则不管它套上多少个幂,其个位数永远是1(显然)。
同理,当ci=0ci=0ci=0或5或6时,其个位数永远是0或5或6.
因为题目限制了cicici不等于222或444或888,所以我们要考虑的数只剩下3,7,93,7,93,7,9了。
当ci=3ci=3ci=3或777时:
因为34≡1(3 ^ 4 ≡ 1(34≡1(modmodmod 101010),747^474 ≡ 1(1(1(modmodmod 101010)
所以cicici的指数
ai^ai^ai...(bi−1个ai)就相当于其mod 4后的结果。
以ci=3ci=3ci=3为例。不论如何,易证ai≡1ai≡1ai≡1或−1−1−1(modmodmod 444)
若ai≡1a_i≡1ai≡1(modmodmod 444),则原式变成了
ci^1^1^1^1^1…..=ci,个位数就是ci。
否则ai≡−1ai≡−1ai≡−1(modmodmod 444),则原式变成了
ci^(-1)^(-1)^(-1)….=ci^(-1)=ci^3,个位数易求。
当ci=9ci=9ci=9时 92≡1(9^2≡1(92≡1(modmodmod 101010),同样的方法处理即可。
其实这道题的bib_ibi并没有实际性的用处,只是用来吓人的。
Code
#include<cstdio>
#include<cctype>
#include<algorithm>
#define for(i,a,b) for(int i = a;i <= b;i++)
using namespace std;
const int N = 100010;
inline int read()
{
int ret = 0,w = 0;
char ch = 0;
while(!isdigit(ch))
{
w |= ch == '-';
ch = getchar();
}
while(isdigit(ch))
{
ret = (ret << 3) + (ret << 1) + (ch ^ 48),ch = getchar();
}
return w ? -ret : ret;
}
inline void write(int x)
{
if(x < 0)
{
putchar('-'),x = -x;
if(size == 1)
puts("");
}
if(x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
int main()
{
//freopen("superpow.in","r",stdin);
//freopen("superpow.out","w",stdout);
int T,n,x,y;
T = read();
while(T--)
{
int ans = 1;
n = read();
for(i,1,n)
{
x = read();
y = read();
int z = x % 10;
if(y == 0)
continue;
if(y == 1)
{
ans = ans * z % 10;
continue;
}
if(z == 0 || z == 1 || z == 5 || z == 6 || z == 9)
{
ans = ans * z % 10;
continue;
}
if(z == 3 || z == 7)
{
if(x % 4 == z)
ans = ans * z % 10;
else
ans = ans * (z * z * z % 10) % 10;
continue;
}
}
write(ans);
puts("");
}
return 0;
}