给定
,求
例如
时,即求
这与上一道题洛谷P4139 上帝与集合的正确用法十分相似,但是仍有区别
推一下这道题目的欧拉公式吧:
定义
所以求
.....
可以写出大致的代码:
,
表示的是模数,这是因为洛谷P4139 上帝与集合的底数都是
没有变化,而这道题目的底数是
,是在变化的
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;
int n, m;
int get_oula(int x){
int sum = x;
for(int i = 2; i * i <= x; i ++){
if(x % i == 0){
sum = sum / i * (i - 1);
while(x % i == 0) x /= i;
}
}
if(x > 1) sum = sum / x * (x - 1);
return sum;
}
int ksm(int a, int b, int mod){
a %= mod;
int sum = 1;
while(b){
if(b & 1) sum = (sum * a) % mod;
b >>= 1;
a = (a * a) % mod;
}
return sum;
}
int dfs(int n, int m){
if(m == 1) return 0;
if(n == 1) return 1;
else{
int oula = get_oula(m);
return ksm(n, dfs(n - 1, oula) + oula, m);
}
}
signed main(){
HelloWorld;
cin >> n;
m = 1000000007;
cout << dfs(n, m) << endl;
return 0;
}
洛谷P4139 上帝与集合只有一个参数
所以
,
表示当前的底数,
表示的是当前的模数。
但是错了,原因在于无脑的加上
,因为洛谷P4139 上帝与集合这道题目的意思就是求解 2 的无限次幂塔模 p,那么2的无限次幂
,指数是
所以无论什么时候都满足大于
,所以无脑加
return ksm(n, dfs(n - 1, oula) + oula, m);扩展欧拉定理是:
-
,
-
,
所以得判断
与
的关系!!!
为什么洛谷P4139 上帝与集合可以无脑加
这里就需要判断大小的关系:
详细解释:
当
时,表示此时需要模上
,那么肯定等于
;此时
,所以所有
;返回
当
时,表示递归到最后一层,那么值就是
;此时递归到最后一层,指数没有了,相当于
,所以
;返回
pair<int, bool> dfs(int n, int m){
if(m == 1) return {0, true};
if(n == 1) return {1, false};
else{
int oula = get_oula(m);
pair<int, bool> next = dfs(n - 1, oula);
int b = next.first;
if(next.second) b += oula;
int now_ans = ksm(n, b, m);
bool now_ans_bool = b >= oula;
return {now_ans, now_ans_bool};
}
}
总代码:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;
int n, m;
int get_oula(int x){
int sum = x;
for(int i = 2; i * i <= x; i ++){
if(x % i == 0){
sum = sum / i * (i - 1);
while(x % i == 0) x /= i;
}
}
if(x > 1) sum = sum / x * (x - 1);
return sum;
}
int ksm(int a, int b, int mod){
a %= mod;
int sum = 1;
while(b){
if(b & 1) sum = (sum * a) % mod;
b >>= 1;
a = (a * a) % mod;
}
return sum;
}
pair<int, bool> dfs(int n, int m){
if(m == 1) return {0, true};
if(n == 1) return {1, false};
else{
int oula = get_oula(m);
pair<int, bool> next = dfs(n - 1, oula);
int b = next.first;
if(next.second) b += oula;
int now_ans = ksm(n, b, m);
bool now_ans_bool = b >= oula;
return {now_ans, now_ans_bool};
}
}
signed main(){
HelloWorld;
cin >> n;
m = 1000000007;
cout << dfs(n, m).first << endl;
return 0;
}



京公网安备 11010502036488号