結果

問題 No.2705 L to R Graph (Another ver.)
ユーザー MagentorMagentor
提出日時 2024-03-16 01:16:18
言語 C++23
(gcc 12.3.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 3,465 bytes
コンパイル時間 6,315 ms
コンパイル使用メモリ 314,912 KB
実行使用メモリ 196,256 KB
最終ジャッジ日時 2024-03-16 01:16:56
合計ジャッジ時間 34,348 ms
ジャッジサーバーID
(参考情報)
judge11 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,676 KB
testcase_01 AC 2 ms
6,676 KB
testcase_02 AC 2 ms
6,676 KB
testcase_03 AC 2 ms
6,676 KB
testcase_04 AC 2 ms
6,676 KB
testcase_05 AC 2 ms
6,676 KB
testcase_06 AC 2 ms
6,676 KB
testcase_07 AC 2 ms
6,676 KB
testcase_08 WA -
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 WA -
testcase_22 WA -
testcase_23 WA -
testcase_24 WA -
testcase_25 WA -
testcase_26 WA -
testcase_27 WA -
testcase_28 WA -
testcase_29 WA -
testcase_30 WA -
testcase_31 WA -
testcase_32 WA -
testcase_33 WA -
testcase_34 WA -
testcase_35 WA -
testcase_36 WA -
testcase_37 WA -
testcase_38 WA -
testcase_39 WA -
testcase_40 WA -
testcase_41 WA -
testcase_42 WA -
testcase_43 WA -
testcase_44 WA -
testcase_45 WA -
testcase_46 WA -
testcase_47 WA -
testcase_48 WA -
testcase_49 WA -
testcase_50 WA -
testcase_51 WA -
testcase_52 WA -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;
#include <atcoder/all>
using namespace atcoder;
#define int long long

void cumsum(std::vector<int>& x, int d = 1) {
    for (int i = d; i < x.size(); i++) {
        x[i] += x[i - d];
    }
}
long long modpow(long long a, long long n, long long mod) {
    long long res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}
signed main() {
    int N, P;
    std::cin >> N >> P;
    int ans = 0;
    std::vector<int> f = {0, 0};
    int fact = 1;
    for (int i = 2; i <= N; i++) {
        f.push_back((modpow(N, N - i, P) * fact) % P);
        fact *= N - i;
        fact %= P;
    }
    std::vector<int> dist(N, 0);
    int cumt = 0;
    int pat = 0;
    for (int i = N - 2; i > 0; i--) {
        cumt += f[i + 2];
        pat += cumt;
        cumt %= P;
        pat %= P;
        dist[i] = pat;
    }
    int backet = 100;
    std::vector<int> pats(N * 2, 0);
    std::vector<std::vector<int>> det(backet + 1, std::vector<int>(N * 2, 0));
    for (int i = 1; i <= N; i++) {
        for (int j = 0; j <= N; j++) {
            if (i * j >= N) {
                break;
            }
            if (j == 0) {
                pats[1] += N - i + 1;
                pats[i * (j + 1)] -= N - i + 1;
                continue;
            }
            if (j > backet) {
                int cnt = 0;
                for (int k = i * j + 1; k < i * (j + 1); k += j) {
                    pats[k] += 1;
                    cnt += 1;
                }
                pats[i * (j + 1)] -= cnt;
            } else {
                det[j][i * j + 1] += 1;
                int cnt = (i * (j + 1) - 2) / j - i + 1;
                det[j][std::min(N * 2 - 1, i * j + 1 + cnt * j)] -= 1;
                pats[i * (j + 1)] -= cnt;
            }
        }
    }
    for (int i = 1; i <= backet; i++) {
        cumsum(det[i], i);
        for (int j = 0; j < N * 2; j++) {
            pats[j] += det[i][j];
        }
    }
    cumsum(pats);
    for (int i = 0; i < N - 1; i++) {
        pats[i] = N * (N + 1) / 2 - pats[i];
        ans += pats[i] * dist[i];
        ans %= P;
    }
    cumsum(f);
    std::vector<std::vector<int>> div(N + 1, std::vector<int>());
    std::vector<std::vector<int>> cum(N + 1, std::vector<int>(1, 0));
    for (int i = 1; i <= N; i++) {
        for (int j = i; j <= N; j += i) {
            div[j].push_back(i);
            cum[i].push_back(cum[i].back() + f[j]);
        }
    }
    for (int i = 1; i <= N; i++) {
        std::vector<int> gcd(div[i].size(), 0);
        for (int j = div[i].size() - 1; j >= 0; j--) {
            gcd[j] += N / div[i][j];
            for (int k = j - 1; k >= 0; k--) {
                if (div[i][j] % div[i][k] == 0) {
                    gcd[k] -= gcd[j];
                }
            }
            int pl = cum[div[i][j]].back() - cum[div[i][j]][i / div[i][j]];
            int plcnt = cum[div[i][j]].size() - 1 - i / div[i][j];
            int mi = cum[div[i][j]].back() - cum[div[i][j]][i / div[i][j] - 1] + f[i - 1] * (i / div[i][j] - 1);
            int micnt = plcnt + 1 + i / div[i][j] - 1;
            ans += (pl + f.back() * (micnt - plcnt) - mi) * gcd[j];
            if (j == 0) {
                ans += (pl + f.back() * (micnt - plcnt) - mi) * N * (N - 1) / 2;
            }
            ans %= P;
        }
    }
    std::cout << (ans * N * (N - 1)) % P << std::endl;
    return 0;
}
0