ccf csp 202012-1

A 期末预测之安全指数

签到

B 期末预测之最佳阈值

签到

排序之后, 处理前缀和, 先行枚举

C 带配额的文件系统

写ex了, 大模拟

D 食材运输

注意到食材就10种, 直接状压,

又发现答案单调, 直接二分

const int N = 1e2, M = 10;

int n, m, _, k, cas;
int a[N][M], d[N][M], v[N], f[1 << M];
vector<PII> h[N];

PII dfs(int x, int fa, int k) {
    int res = 0, mx = 0;
    for (auto& [y, c] : h[x]) if (y ^ fa) {
        auto cur = dfs(y, x, k);
        if (~cur.fi) res += cur.fi + c * 2, umax(mx, cur.se + c);
    }
    return res ? PII{ res - (_ == x) * mx, mx } : a[x][k] ? PII{ 0, 0 } : PII{ -1, 0 };
}

bool check(int mid) {
    memset(v, 0, sizeof v); memset(f, 0x3f, sizeof f); f[0] = 0;
    rep(i, 0, n - 1) rep(j, 0, k - 1) if (~d[i][j] && d[i][j] <= mid) v[i] |= 1 << j;
    rep(i, 0, n - 1) rep(j, 0, (1 << k) - 1) umin(f[j | v[i]], f[j] + 1);
    return f[(1 << k) - 1] <= m;
}

int main() {
    IOS; cin >> n >> m >> k;
    rep(i, 0, n - 1) rep(j, 0, k - 1) cin >> a[i][j];
    rep(i, 2, n) { int u, v, c; cin >> u >> v >> c; --u, --v; h[u].pb(v, c); h[v].pb(u, c); }
    rep(i, 0, n - 1) { _ = i;  rep(j, 0, k - 1) d[i][j] = dfs(i, -1, j).fi; }
    int l = 0, r = 1e8;
    while (l < r) {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    cout << l;
    return 0;
}

E 星际旅行

线段树基操, 只不过是维护3个序列, 注意标记下压顺序, 先旋转, 再区间乘, 再区间加

const int N = 4e4 + 5, mod = 1e9 + 7;

struct query { ll op, l, r, x[3]; } a[N];

struct BIT {
    struct node { int l, r, c; ll val[3], tag[5]; } tr[N * 40];
    void push_up(int rt) { rep(i, 0, 2) tr[rt].val[i] = (tr[rt << 1].val[i] + tr[rt << 1 | 1].val[i]) % mod; }
    void push_down(int rt) {
        if (tr[rt].tag[4] == 1)
            swap(tr[rt << 1].val[0], tr[rt << 1].val[1]), swap(tr[rt << 1].val[1], tr[rt << 1].val[2]),
            swap(tr[rt << 1].tag[0], tr[rt << 1].tag[1]), swap(tr[rt << 1].tag[1], tr[rt << 1].tag[2]),
            swap(tr[rt << 1 | 1].val[0], tr[rt << 1 | 1].val[1]), swap(tr[rt << 1 | 1].val[1], tr[rt << 1 | 1].val[2]),
            swap(tr[rt << 1 | 1].tag[0], tr[rt << 1 | 1].tag[1]), swap(tr[rt << 1 | 1].tag[1], tr[rt << 1 | 1].tag[2]);
        if (tr[rt].tag[4] == 2)
            swap(tr[rt << 1].val[0], tr[rt << 1].val[2]), swap(tr[rt << 1].val[1], tr[rt << 1].val[2]),
            swap(tr[rt << 1].tag[0], tr[rt << 1].tag[2]), swap(tr[rt << 1].tag[1], tr[rt << 1].tag[2]),
            swap(tr[rt << 1 | 1].val[0], tr[rt << 1 | 1].val[2]), swap(tr[rt << 1 | 1].val[1], tr[rt << 1 | 1].val[2]),
            swap(tr[rt << 1 | 1].tag[0], tr[rt << 1 | 1].tag[2]), swap(tr[rt << 1 | 1].tag[1], tr[rt << 1 | 1].tag[2]);
        if (tr[rt].tag[3] ^ 1) rep(i, 0, 2)
            tr[rt << 1].val[i] = tr[rt << 1].val[i] * tr[rt].tag[3] % mod,
            tr[rt << 1].tag[i] = tr[rt << 1].tag[i] * tr[rt].tag[3] % mod,
            tr[rt << 1 | 1].val[i] = tr[rt << 1 | 1].val[i] * tr[rt].tag[3] % mod,
            tr[rt << 1 | 1].tag[i] = tr[rt << 1 | 1].tag[i] * tr[rt].tag[3] % mod;
        rep(i, 0, 2) if (tr[rt].tag[i])
            tr[rt << 1].val[i] = (tr[rt << 1].val[i] + tr[rt].tag[i] * tr[rt << 1].c % mod) % mod,
            tr[rt << 1].tag[i] = (tr[rt << 1].tag[i] + tr[rt].tag[i]) % mod,
            tr[rt << 1 | 1].val[i] = (tr[rt << 1 | 1].val[i] + tr[rt].tag[i] * tr[rt << 1 | 1].c % mod) % mod,
            tr[rt << 1 | 1].tag[i] = (tr[rt << 1 | 1].tag[i] + tr[rt].tag[i]) % mod;
        tr[rt << 1].tag[3] = tr[rt << 1].tag[3] * tr[rt].tag[3] % mod;
        tr[rt << 1 | 1].tag[3] = tr[rt << 1 | 1].tag[3] * tr[rt].tag[3] % mod;
        tr[rt << 1].tag[4] = (tr[rt << 1].tag[4] + tr[rt].tag[4]) % 3;
        tr[rt << 1 | 1].tag[4] = (tr[rt << 1 | 1].tag[4] + tr[rt].tag[4]) % 3;
        memset(tr[rt].tag, 0, sizeof tr[rt].tag); tr[rt].tag[3] = 1;
    }
    void build(int rt, int l, int r, vector<int>& c) {
        tr[rt].l = l, tr[rt].r = r, tr[rt].c = c[r + 1] - c[l];
        memset(tr[rt].val, 0, sizeof tr[rt].val);
        memset(tr[rt].tag, 0, sizeof tr[rt].tag); tr[rt].tag[3] = 1;
        if (l == r) return;
        int mid = l + r >> 1;
        build(rt << 1, l, mid, c); build(rt << 1 | 1, mid + 1, r, c);
    }
    void change(int rt, query& q) {
        if (tr[rt].l >= q.l && tr[rt].r <= q.r) {
            if (q.op == 1) rep(i, 0, 2)
                tr[rt].val[i] = (tr[rt].val[i] + q.x[i] * tr[rt].c % mod) % mod, tr[rt].tag[i] = (tr[rt].tag[i] + q.x[i]) % mod;
            else if (q.op == 2) {
                rep(i, 0, 2) tr[rt].val[i] = tr[rt].val[i] * q.x[0] % mod, tr[rt].tag[i] = tr[rt].tag[i] * q.x[0] % mod;
                tr[rt].tag[3] = tr[rt].tag[3] * q.x[0] % mod;
            }
            else {
                swap(tr[rt].val[0], tr[rt].val[1]), swap(tr[rt].val[1], tr[rt].val[2]);
                swap(tr[rt].tag[0], tr[rt].tag[1]), swap(tr[rt].tag[1], tr[rt].tag[2]);
                tr[rt].tag[4] = (tr[rt].tag[4] + 1) % 3;
            }
            return;
        }
        push_down(rt); int mid = tr[rt].l + tr[rt].r >> 1;
        if (mid >= q.l) change(rt << 1, q);
        if (mid < q.r) change(rt << 1 | 1, q);
        push_up(rt);
    }
    query ask(int rt, int l, int r) {
        query ans, res;
        if (tr[rt].l >= l && tr[rt].r <= r) return memcpy(ans.x, tr[rt].val, sizeof ans.x), ans;
        push_down(rt); int mid = tr[rt].l + tr[rt].r >> 1;
        if (mid >= l) ans = ask(rt << 1, l, r);
        else memset(ans.x, 0, sizeof ans.x);
        if (mid < r) { res = ask(rt << 1 | 1, l, r); rep(i, 0, 2) ans.x[i] = (ans.x[i] + res.x[i]) % mod; }
        return ans;
    }
} bit;

int n, m, _, k, cas;
vector<int> c;

int main() {
    IOS; cin >> n >> m;
    rep(i, 1, m) {
        cin >> a[i].op >> a[i].l >> a[i].r; c.pb(a[i].l); c.pb(a[i].r + 1);
        if (a[i].op == 1) cin >> a[i].x[0] >> a[i].x[1] >> a[i].x[2];
        else if (a[i].op == 2) cin >> a[i].x[0];
    }
    sort(all(c)); c.erase(unique(all(c)), c.end());
    bit.build(1, 0, c.size() - 1, c);
    rep(i, 1, m) {
        a[i].l = lower_bound(all(c), a[i].l) - c.begin(); a[i].r = upper_bound(all(c), a[i].r) - c.begin() - 1;
        if (a[i].op ^ 4) bit.change(1, a[i]);
        else {
            a[i] = bit.ask(1, a[i].l, a[i].r); ll ans = 0;
            rep(j, 0, 2) ans = (ans + sqr(a[i].x[j])) % mod;
            cout << ans << '\n';
        }
    }
    return 0;
}
posted @ 2021-03-17 20:47  洛绫璃  阅读(97)  评论(0编辑  收藏  举报