結果
| 問題 |
No.2576 LCM Pattern
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-12-06 16:33:31 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 2,000 ms |
| コード長 | 1,475 bytes |
| コンパイル時間 | 2,079 ms |
| コンパイル使用メモリ | 175,116 KB |
| 実行使用メモリ | 5,376 KB |
| 最終ジャッジ日時 | 2024-09-27 01:34:34 |
| 合計ジャッジ時間 | 2,671 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 23 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
const long MODULO=998244353L;
long modpow(long a, long n){
long ans=1L;
while(n){
if(n&1L){
ans*=a;
ans%=MODULO;
}
a=a*a%MODULO;
n>>=1;
}
return ans;
}
map<long, long> divisors(long n){
map<long, long> M;
long i=2L;
while(i*i<=n){
if(n%i==0){
M[i]++;
n/=i;
}else{
i++;
}
}
if(n>1L){
M[n]++;
}
return M;
}
long num_of_divisors(const map<long, long>& M){
long ans=1L;
for(auto m:M){
ans*=(m.second+1);
}
return ans;
}
long num_of_divisors(long n){
return num_of_divisors(divisors(n));
}
int main(){
long n,m;
cin >> n >> m;
//mの約数を取得(数列の要素の候補)
map<long, long> M=divisors(m);
vector<long> V;
for(auto m:M){
V.push_back(m.first);
}
long k=(long)V.size();
//mの約数の組み合わせは「mの約数の個数」のn乗
//但し、最小公倍数がm未満になる場合もあるので、+=する。
//例:M=12の場合
//「最小公倍数が12の約数」-「最小公倍数が6の約数」-「最小公倍数が4の約数」+「最小公倍数が2の約数」
long ans=0L;
for(long j=0L;j<(1L<<k);j++){
long f=1L; //符号
long x=m; //上のコメントの中で「12」「6」「4」「2」にあたるもの
for(long i=0L;i<k;i++){
if(j&(1L<<i)){
x/=V[i];
f*=(-1L);
}
}
ans+=f*modpow(num_of_divisors(x),n);
ans=((ans%MODULO)+MODULO)%MODULO;
}
cout << ans << endl;
return 0;
}