AC

许诺  •  1天前


#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;

using ll = long long;

ll gcd(ll a, ll b) {

while (b) {
    a %= b;
    swap(a, b);
}
return a;

}

ll lcm(ll a, ll b) {

return a / gcd(a, b) * b;

}

int main() {

int N, M;
cin >> N >> M;

unordered_map<ll, ll> dp;
dp[0] = 1; // sum 0, lcm 1 (initial state)

for (int k = 1; k <= N; ++k) {
    unordered_map<ll, ll> new_dp;
    for (auto& [sum_lcm, count] : dp) {
        ll sum = sum_lcm >> 20;
        ll current_lcm = sum_lcm & ((1 << 20) - 1;
        
        // Option 1: do not take k
        ll new_sum_lcm = (sum << 20) | current_lcm;
        new_dp[new_sum_lcm] = (new_dp[new_sum_lcm] + count) % M;
        
        // Option 2: take k
        ll new_sum = sum + k;
        ll new_lcm = current_lcm == 0 ? k : lcm(current_lcm, k);
        new_sum_lcm = (new_sum << 20) | new_lcm;
        new_dp[new_sum_lcm] = (new_dp[new_sum_lcm] + count) % M;
    }
    dp = move(new_dp);
}

ll result = 0;
for (auto& [sum_lcm, count] : dp) {
    ll sum = sum_lcm >> 20;
    ll current_lcm = sum_lcm & ((1 << 20) - 1);
    if (sum == N && current_lcm != 0) {
        result = (result + current_lcm) % M;
    }
}

cout << result << endl;
return 0;

}


评论:

请先登录,才能进行评论