题目
Given a positive integer N, you should output the most right digit of N^N.
Input
The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow.
Each test case contains a single positive integer N(1<=N<=1,000,000,000).
Output
For each test case, you should output the rightmost digit of N^N.
Sample Input
2
3
4
Sample Output
7
6
Hint
In the first case, 3 * 3 * 3 = 27, so the rightmost digit is 7.
In the second case, 4 * 4 * 4 * 4 = 256, so the rightmost digit is 6.
分析
1.快速幂
先看看怎么求a的a次方更快:
你看,只有指数对应的位为1,才相乘
而且每个乘的数都有规律,
假设a^2^0=c,a^2^1=c*c=c1,
a^2^2=c1*c1
那就用一个数存c,然后循环乘就行,
至于什么时候算在最终结果之内,只要看指数对应的位是否为一
int poww(int a,int b){int ans=1,base=a;while(b!=0){if(b&1!=0)ans*=base;base*=base;b>>=1;}return ans;
}
我解释不太清楚,看看别人怎么解释的吧
由于是二进制,很自然地想到用位运算这个强大的工具: & 和 >> ,&运算通常用于二进制取位操作,例如一个数 & 1 的结果就是取二进制的最末位。还可以判断奇偶x&1==0为偶,x&1==1为奇。>>运算比较单纯,二进制去掉最后一位
以b==11为例,b=>1011,二进制从右向左算,但乘出来的顺序是 a^(2^0) * a^(2^1) * a^(2^3),是从左向右的。我们不断的让base*=base目的即是累乘,以便随时对ans做出贡献。
其中要理解base*=base这一步,看:::base*base==base^2,下一步再乘,就是base^2*base^2==base^4,然后同理 base^4 * base4 = base^8 ,,,,, see?是不是做到了base–>base^2–>base^4–>base^8–>base^16–>base^32…….指数正是 2^i 啊,再看上面的例子,a¹¹ = a^(2^0) * a^(2^1) * a^(2^3),这三项是不是完美解决了,,嗯,快速幂就是这样。
2.取模运算
定理:
(a*b)%c=(a%c)*(b%c)%c
于是,求最后n位
int quick(int a,int b,int c)
{ int ans=1; //记录结果 a=a%c; //预处理,使得a处于c的数据范围之下 while(b!=0) { if(b&1) ans=(ans*a)%c; //如果b的二进制位不是0,那么我们的结果是要参与运算的 b>>=1; //二进制的移位操作,相当于每次除以2,用二进制看,就是我们不断的遍历b的二进制位 a=(a*a)%c; //不断的加倍 } return ans;
}
本题代码
#include<iostream>
using namespace std;int quick(int a,int b,int n)
{ int ans =1;a=a%n;while(b!=0){if(b&1)ans=(ans*a)%n;a=a*a%n;b>>=1;} return ans;
}
int main(){int n,a;cin>>n;while(n--){cin>>a;cout<<quick(a,a,10)<<endl;}
}