95pts,WA#19求调

P7077 [CSP-S2020] 函数调用

steambird @ 2024-04-27 21:37:08

大致思路:先倒着扫一遍确定乘法,再正着扫一遍

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

inline void train() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}

constexpr int N = 1e5 + 4, Q = 1e6 + 3;
constexpr long long MODER = 998244353;

long long origin[N], timing[N], op_timing[N], op_adding[N], counter[N], adding[N];
long long modifiers[N];

long long final_timing = 1ll;

vector<int> active[N], passive[N];
int active_ins[N], passive_ins[N];
long long op_adding_at[N];
short node_type[N];

long long g_timestamp = 0;  
struct order {
    int to, depth;
    long long timestamp;

    order(int to = 0, int depth = 0, long long alignment = -1) : to(to), depth(depth),
        timestamp(g_timestamp + alignment) {
        if (alignment < 0) {
            timestamp -= alignment;
            g_timestamp++;
        }
    }
};

bool operator > (const order &a, const order &b) {
    if (a.depth == b.depth) return a.timestamp > b.timestamp;
    return a.depth < b.depth;
}

long long fastpow(long long a, long long b) {
    if (b <= 0) return 1ll;
    else if (b & 1) return a * fastpow(a, b - 1) % MODER;
    else {
        long long s = fastpow(a, b >> 1);
        return s * s % MODER;
    }
}

priority_queue<order, vector<order>, greater<order> > pq;

int n, m, q;

signed main() {
    train();

    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> origin[i];
    }
    cin >> m;
    for (int i = 1; i <= m; i++) {
        int ns;
        timing[i] = 1ll;
        cin >> node_type[i];
        switch (node_type[i]) {
        case 1:
            cin >> op_adding_at[i] >> op_adding[i];
            break;
        case 2:
            cin >> op_timing[i];
            timing[i] = op_timing[i];
            break;
        case 3:
            cin >> ns;
            for (int j = 0; j < ns; j++) {
                int x;
                cin >> x;
                active[i].push_back(x);
                active_ins[x]++;
                passive[x].push_back(i);
                passive_ins[i]++;
            }
            break;
        }
    }
    cin >> q;
    m++;
    timing[m] = 1ll;
    node_type[m] = 3;
    counter[m] = 1;
    adding[m] = 1ll;
    for (int i = 0; i < q; i++) {
        int x;
        cin >> x;
        active[m].push_back(x);
        active_ins[x]++;
        passive[x].push_back(m);
        passive_ins[m]++;
    }
    for (int i = 1; i <= m; i++) {
        if (passive_ins[i] == 0) pq.push(order(i));
    }
    for (int i = 0; i < m; i++) {
        order pf = pq.top();
        pq.pop();
        for (auto &j : passive[pf.to]) {
            timing[j] = (timing[j] * timing[pf.to]) % MODER;
            passive_ins[j]--;
            if (passive_ins[j] == 0) {
                pq.push(order(j, pf.depth + 1));
            }
        }
    }

    while (!pq.empty()) {
        pq.pop();
    }

    for (int i = 1; i <= m; i++) {
        if (active_ins[i] == 0) pq.push(order(i));
    }
    for (int i = 0; i < m; i++) {
        order pf = pq.top();
        pq.pop();
        switch (node_type[pf.to]) {
        case 1:
            modifiers[op_adding_at[pf.to]] = (modifiers[op_adding_at[pf.to]] + (adding[pf.to] * op_adding[pf.to] % MODER)) % MODER;
            break;
        case 2:
            final_timing = (final_timing * fastpow(timing[pf.to], counter[pf.to] % (MODER-1))) % MODER;
            break;
        case 3:
            long long accu = 1ll;
            for (int jr = active[pf.to].size() - 1; jr >= 0; jr--) {
                auto &j = active[pf.to][jr];
                counter[j] += counter[pf.to];
                active_ins[j]--;
                adding[j] = (adding[j] + (adding[pf.to] * accu) % MODER) % MODER;
                if (active_ins[j] == 0) {
                    pq.push(order(j, pf.depth + 1, jr));
                }
                accu = (accu * timing[j]) % MODER;
            }
            g_timestamp += active[pf.to].size() + 1;
            break;
        }
    }
    for (int i = 1; i <= n; i++) {
        long long timed = (origin[i] * final_timing) % MODER;
        long long added = (timed + modifiers[i]) % MODER;
        cout << added << ' ';
    }
    cout << endl;

    return 0;
}

by steambird @ 2024-04-28 18:34:58

解决:指数要取模(而且根据费马小是模 p-1


|