結果
| 問題 |
No.3187 Mingle
|
| コンテスト | |
| ユーザー |
pockyny
|
| 提出日時 | 2025-07-07 00:29:33 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 700 ms / 2,500 ms |
| コード長 | 1,683 bytes |
| コンパイル時間 | 1,212 ms |
| コンパイル使用メモリ | 81,832 KB |
| 実行使用メモリ | 39,372 KB |
| 最終ジャッジ日時 | 2025-07-07 00:30:06 |
| 合計ジャッジ時間 | 20,059 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 30 |
ソースコード
#include <iostream>
#include <vector>
#include <atcoder/modint>
using namespace std;
using namespace atcoder;
using mint = modint;
typedef long long ll;
ll INF = 1000000000000000000;
template<typename T = ll>
struct segment_tree{
int n; vector<T> seg;
T e(){return 0;}
T op(T a,T b){return (a + b);}
segment_tree(){}
segment_tree(int sz){n = sz; seg.resize(2*n,e());}
segment_tree(vector<T> v){
n = v.size(); seg.resize(2*n,e());
for(int i=0;i<n;i++) seg[i + n] = v[i];
for(int i=n - 1;i>0;i--) seg[i] = op(seg[i<<1],seg[i<<1|1]);
}
void init(int sz){n = sz; seg.resize(2*n);}
void update(int p,T val){
for(seg[p += n] = val;p>1;p>>=1) seg[p>>1] = op(seg[p],seg[p^1]);
}
T get(int p){return seg[p + n];}
T query(int l,int r){
T res = e();
for(l += n,r += n; l<r;l>>=1,r>>=1){
if(l&1) res = op(res,seg[l++]);
if(r&1) res = op(res,seg[--r]);
}
return res;
}
void clear(){for(int i=0;i<2*n;i++) seg[i] = e();}
};
const int MX = 300000;
vector<int> di[MX + 10];
mint p[MX + 10];
int main(){
int i,j,n,P; cin >> n >> P;
mint::set_mod(P);
for(i=1;i<=MX;i++){
for(j=i;j<=MX;j+=i) di[j].push_back(i);
}
segment_tree<mint> seg(MX + 1);
p[n] = 1;
seg.update(n,p[n]/(mint)(n - di[n].size()));
for(i=n - 1;i>=3;i--){
for(int x:di[i]){
p[i] += seg.query(i + 1,min(x + i,MX + 1));
}
if(i>2) seg.update(i,p[i]/(mint)(i - di[i].size()));
}
mint ans = 0;
for(i=3;i<=n;i++){
ans += p[i]/(1 - (mint)di[i].size()/(mint)i);
}
cout << ans.val() << "\n";
}
pockyny