abc-245(D~F)

D:

image
求多项式c的系数
倒序模拟:

题解:

const int N = 1010;
int a[N], c[N];
int b[N];
void solve(int Case) {
    int n, m;
    cin >> n >> m;
    for (int i = 0; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 0; i <= n + m; i++) {
        cin >> c[i];
    }
    memset(b, 0x3f, sizeof b);
    for (int i = m; i >= 0; i--) {
        for (int j = n; j >= 0; j--) {
            int x = i + j;
            if (b[i] != 0x3f3f3f3f3f3f3f3f) {
                c[x] -= b[i] * a[j];
            } else {
                if (!a[j]) b[i] = 0;
                else b[i] = c[x] / a[j];
            }
        }
    }
    for (int i = 0; i <= m; i++) {
        cout << b[i] << ' ';
    }
}

E:

image
可以按照a来排序,然后二分找到比a大的所有y中的大于等于b的数,并且删去

题解:

const int N = 200010;
using PII = pair<int, int> ;
PII a[N], b[N];
void solve(int Case) {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        auto &[x, y] = a[i];
        cin >> x ;
    }

    for (int i = 1; i <= n; i++) {
        auto &[x, y] = a[i];
        cin >> y ;
    }
    for (int i = 1; i <= m; i++) {
        auto &[x, y] = b[i];
        cin >> x;
    }

    for (int i = 1; i <= m; i++) {
        auto &[x, y] = b[i];
        cin  >> y;
    }
    sort(a + 1, a + 1 + n, greater<PII>());
    sort(b + 1, b + 1 + m, greater<PII>());
    int idx = 1;
    multiset<int> s;
    for (int i = 1; i <= n; i++) {
        auto [x, y] = a[i];
        while (idx <= m and b[idx].first >= x) s.insert(b[idx].second), idx++;
        auto it = s.lower_bound(y);
        if (it == s.end()) {
            cout << "No" << nline;
            return;
        }
        s.erase(it);
    }
    cout << "Yes" << nline;

}

F:

image
求每个可以走成死循环的起点

题解:

tarjan缩点,size大于1的强连通分量的内的所有点都满足条件,同时该分量的前驱也满足条件,
缩点后反向跑拓扑

const int N = 200010;
vector<int> h[N], g[N];
int dfn[N], low[N], id[N], S[N], vis[N];
int timestamp, scc_cnt;
stack<int> s;
int deg[N];
int ok[N];
void tarjan(int u) {
    s.push(u);
    vis[u] = true;
    dfn[u] = low[u] = ++timestamp;
    for (auto i : h[u]) {
        if (!dfn[i]) {
            tarjan(i);
            low[u] = min(low[u], low[i]);
        } else if (vis[i]) low[u] = min(low[u], dfn[i]);
    }
    if (low[u] == dfn[u]) {
        ++scc_cnt;
        int y;
        do {
            y = s.top();
            s.pop();
            vis[y] = false;
            id[y] = scc_cnt;
            S[scc_cnt]++;
        } while (y != u);
    }
}
void solve(int Case) {
    int n, m;
    cin >> n >> m;
    for (; m--;) {
        int a, b;
        cin >> a >> b;
        h[a].push_back(b);
    }
    for (int i = 1; i <= n; i++) {
        if (!dfn[i]) {
            tarjan(i);
        }
    }
    for (int i = 1; i <= n; i++) {
        for (auto j : h[i]) {
            int a = id[i], b = id[j];
            if (a != b) {
                g[b].push_back(a);
                deg[a]++;
            }
        }
    }
    queue<int> q;
    for (int i = 1; i <= scc_cnt; i++) {
        if (!deg[i]) {
            q.push(i);
            if (S[i] > 1) ok[i] = true;
        }
    }
    while (q.size()) {
        auto t = q.front();
        q.pop();
        for (auto i : g[t]) {
            if (S[i] > 1 or ok[t]) {
                ok[i] = true;
            }
            if (--deg[i] == 0) {
                q.push(i);
            }
        }
    }
    int res = 0;
    for (int i = 1; i <= scc_cnt; i++) {
        if (ok[i]) res += S[i];
    }
    cout << res << nline;
}
posted @ 2022-03-27 14:13  指引盗寇入太行  阅读(55)  评论(0编辑  收藏  举报