結果
| 問題 |
No.181 A↑↑N mod M
|
| コンテスト | |
| ユーザー |
koyumeishi
|
| 提出日時 | 2015-08-02 09:35:55 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 5,000 ms |
| コード長 | 3,060 bytes |
| コンパイル時間 | 717 ms |
| コンパイル使用メモリ | 78,320 KB |
| 実行使用メモリ | 5,248 KB |
| 最終ジャッジ日時 | 2024-11-24 03:23:01 |
| 合計ジャッジ時間 | 1,720 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 6 |
| other | AC * 37 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:163:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
163 | scanf("%d%d%d", &A,&N,&M);
| ~~~~~^~~~~~~~~~~~~~~~~~~~
ソースコード
#include <iostream>
#include <vector>
#include <cstdio>
#include <sstream>
#include <map>
#include <string>
#include <algorithm>
#include <queue>
#include <cmath>
#include <set>
using namespace std;
long long gcd(long long a, long long b){
if(b==0) return a;
return gcd(b, a%b);
}
long long lcm(long long a, long long b){
if(a<b) swap(a,b);
if(b==1) return a;
return a * (b/gcd(a,b));
}
//O (sqrt a)
long long CarmichaelFunction(long long a){
long long ret = 1;
for(long long i=2; i*i<=a; i++){
if(a%i != 0) continue;
int cnt = 0;
long long x = 1;
while(a%i == 0){
a /= i;
x *= i;
cnt++;
}
if(i==2){
if(cnt <= 2) ret *= i;
else ret *= 1<<(cnt-2);
}else{
ret = lcm(ret, x/i * (i-1));
}
}
if(a>1){
ret = lcm(ret, a-1);
}
return ret;
}
int carmichaelLambda(int n) {
int ans = 1;
if (n % 8 == 0) n /= 2;
for (int d = 2; d <= n; ++d) {
if (n % d == 0) {
int y = d - 1;
n /= d;
while (n % d == 0) n /= d, y *= d;
ans = lcm(ans, y);
}
}
return ans;
}
long long mypow(long long x, long long y, long long MOD){
if(x==0 && y!=0) return 0;
long long ret=1LL;
while(y>0LL){
if(y&1LL) ret = (ret * x) % MOD;
x = (x*x) % MOD;
y >>= 1LL;
}
return ret;
}
pair<int,int> hoge(long long x, long long m){
int u=0, v=0;
long long g = gcd(x,m);
while(g != 1){
m /= g;
u++;
g = gcd(x,m);
}
long long l = CarmichaelFunction(m);
v = l;
return {u,v};
}
pair<int,int> func(long long A, long long M){
int u=0,v=0;
vector<int> memo(M+1, -1);
for(long long i=0, val=1; i<M; i++, val=val*A%M){
if(memo[val] >= 0){
u = memo[val];
v = i - memo[val];
break;
}
memo[val] = i;
}
cout << mypow(A, v, M) << endl;
return {u,v};
}
// A^A^A...^A > u
bool greater__(long long A, long long N, long long u){
if(u==0) return true;
if(A==1) return A > u;
double val = 1;
for(int i=0; i<N; i++){
if(val>u) return true;
val = pow(1.0*A, val);
}
return false;
}
long long tetoration(long long A, long long N){
long long ret = 1;
while(N){
ret = mypow(A, ret, 1LL<<50);
N--;
}
return ret;
}
ostream& operator <<(ostream& os, pair<int,int>& p){
os << p.first << " " << p.second;
return os;
}
long long dfs(long long A, long long N, long long u, long long M){
if(A==0) return 0;
if(N==0){
return 1%M;
}
if(M==1){
return 0;
}
if(A%M == 0){
return 0;
}
//auto x = func(A%M,M);
auto x = hoge(A%M,M);
bool g = greater__(A,N-1, x.first);
if(g==false){
return mypow(A, tetoration(A,N-1) , M);
}
long long ret = dfs(A, N-1, x.first, x.second) - x.first + x.second*1000;
ret = mypow(A, ret, M);
ret = ret * mypow(A, x.first, M) % M;
return ret%M;
}
int main(){
int A,N,M;
//cin >> A >> N >> M;
scanf("%d%d%d", &A,&N,&M);
if(M==1){
printf("0\n");
//cout << 0 << endl;
return 0;
}
if(N==0){
printf("1\n");
//cout << 1 << endl;
return 0;
}
if(A==1){
printf("1\n");
//cout << 1 << endl;
return 0;
}
long long ans = dfs(A, N, 0, M);
//cout << ans << endl;
printf("%lld\n", ans);
return 0;
}
koyumeishi