2021牛客寒假算法基础集训营1 H. 幂塔个位数的计算

链接

https://ac.nowcoder.com/acm/contest/9981/H

题意

求底数为 $a$,层数 $n$ 为的幂塔的个位数 $(1\le a,n\le10^{100000})$。

思路

答案为 $(a\uparrow\uparrow n)%10$,考虑通过扩展欧拉定理降幂。

因为 $\varphi(10)=4,\varphi(4)=2,\varphi(2)=1$,所以只要计算最外面的三层就可。

  • 对于 $4$ 取模,只需要知道 $a$ 的最后两位;
  • 对于 $2,10$ 取模,只需要知道 $a$ 的最后一位。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <bits/stdc++.h>
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(),(x).end()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define FI first
#define SE second
using namespace std;
typedef double DB;
typedef long double LD;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<PII> VPII;
//head
int qpow(int a,int b) {
int ret=1;
while(b) {
if(b&1) ret*=a;
a*=a;
b>>=1;
}
return ret;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string a,n;
cin>>a>>n;
int t1=a[SZ(a)-1]-'0',t2=t1;
if(SZ(a)>1) t2+=(a[SZ(a)-2]-'0')*10;
if(SZ(n)==1&&n[0]=='1') return cout<<t1<<'\n',0;
if(SZ(n)==1&&n[0]=='2') return cout<<qpow(t1,t2<4?t2:t2%4+4)%10<<'\n',0;
else {
int t=qpow(t2,t1<2?t1:t1%2+2);
return cout<<qpow(t1,t<4?t:t%4+4)%10<<'\n',0;
}
return 0;
}