QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#742809#9619. 乘积,欧拉函数,求和chatoyane#TL 0ms3640kbC++203.1kb2024-11-13 17:22:062024-11-13 17:22:08

Judging History

你现在查看的是最新测评结果

  • [2024-11-13 17:22:08]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:3640kb
  • [2024-11-13 17:22:06]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

using LL = long long;
using db = double;
#define endl '\n'

const LL mod = 998244353;
LL Norm(LL x)
{
    return ((x % mod) + mod) % mod;
}
LL add(LL x, LL y)
{
    return Norm(x + y);
}
LL mul(LL x, LL y)
{
    return Norm(x * y);
}
LL qpow(LL a, LL b)
{
    LL ans = 1, res = a;
    while (b)
    {
        if (b & 1)
            ans = mul(ans, res);
        res = mul(res, res);
        b /= 2;
    }
    return ans;
}

const int N = 3001;
vector<int> Pr;
int vis[N], b[N], tot;

void init()
{
    for (int i = 2; i < N; ++i)
    {
        if (vis[i])
            continue;
        Pr.push_back(i);
        b[i] = tot;
        tot++;
        for (int j = i * 2; j < N; j += i)
        {
            vis[j] = 1;
        }
    }
}

using BT = bitset<435>;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    init();
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; ++i)
        cin >> a[i];
    a[0] = 1;

    auto divide = [&](int x) -> vector<pair<int, int>>
    {
        vector<pair<int, int>> ans;
        for (int i = 2; i * i <= x; ++i)
        {
            if (x % i == 0)
            {
                int cnt = 0;
                while (x % i == 0)
                    x /= i, cnt++;
                ans.push_back({i, cnt});
            }
        }
        if (x > 1)
            ans.push_back({x, 1});
        return ans;
    };

    vector<BT> stu(n + 1);
    for (int i = 1; i <= n; ++i)
    {
        auto mp = divide(a[i]);
        // cerr << "i = " << i << endl;
        for (auto [p, e] : mp)
        {
            // cerr << "p = " << p << " e = " << e << endl;
            // cerr << "b[p] = " << b[p] << endl;
            stu[i][b[p]] = 1;
        }
    }

    auto cmp = [](const auto &a)
    {
        // return std::hash{}(a.first);
        return std::hash<uint64_t>{}(std::hash<int>{}(a.first) ^ std::hash<BT>{}(a.second));
    };

    unordered_map<pair<int, BT>, LL, decltype(cmp)> mp(10, cmp);
    function<LL(int, BT)> dfs = [&](int i, BT s) -> LL
    {
        if (i > n)
            return 1;
        if (mp.count({i, s}))
            return mp[{i, s}];
        // cerr << "----------" << endl;
        LL res = a[i];
        auto rem = ((stu[i] & s) ^ (stu[i]));
        for (int j = rem._Find_first(); j != rem.size(); j = rem._Find_next(j))
        {
            LL p = Pr[j];
            // cerr << "p = " << p << endl;
            res /= p;
            res *= (p - 1);
        }
        // cerr << "i = " << i << " res = " << res << endl;
        LL sum = 1;
        for (int j = i + 1; j <= n; ++j)
        {
            sum = add(sum, dfs(j, s | stu[i]));
        }
        LL ans = mul(res, sum);
        mp[{i, s}] = ans;
        // cerr << "i = " << i << " s = " << s << " ans = " << ans << endl;
        // cerr << "sum = " << sum << " res = " << res << endl;
        return ans;
    };
    LL ans = dfs(0, BT());
    cout << ans << endl;
    return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 3624kb

input:

5
1 6 8 6 2

output:

892

result:

ok single line: '892'

Test #2:

score: 0
Accepted
time: 0ms
memory: 3640kb

input:

5
3 8 3 7 8

output:

3157

result:

ok single line: '3157'

Test #3:

score: -100
Time Limit Exceeded

input:

2000
79 1 1 1 1 1 1 2803 1 1 1 1 1 1 1609 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2137 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 613 1 499 1 211 1 2927 1 1 1327 1 1 1123 1 907 1 2543 1 1 1 311 2683 1 1 1 1 2963 1 1 1 641 761 1 1 1 1 1 1 1 1 1 1 1 1489 2857 1 1 1 1 1 1 1 1 1 1 1 1 1 967 1 821 1 1 1 1 2143 1861...

output:


result: