2024.12.28 CW 模拟赛

题面 & 题解

T1

算法

折半搜索.

思路

因为 \(a, b \le 10^{11}\), 直接搜索肯定不行, 考虑折半然后合并.

搜索是简单的, 怎么合并呢?
假设左半部分是 \(a\), 右半部分是 \(b\), 因为要满足是 \(x\) 的倍数, 所以 \(a \times 10^k + b \equiv 0 \mod x\), 其中 \(k\)\(b\) 的位数.

代码就不放了, 因为没调出来.

T4

原题: P7862

算法

树状数组.

思路

考虑最后的答案是什么, 如果制作时间 \(t_i\) 均为 0, 那么答案最大为 \(\sum_{i = 1}^n l_i\).
如果算上时间, 那么每个人 \(i\) 一定要等到前 \(1 \sim i - 1\) 个人做完才会做他的, 那么答案就为 \(\sum_{i = 1}^n l_i - \sum_{i = 1}^n \sum_{j = 1}^i t_j\).
不难发现, 后面那坨式子可以化简为 \(\sum_{i = 1}^n (n - i + 1) t_i\), 所以原式就成了 \(\sum_{i = 1}^n l_i - \sum_{i = 1}^n (n - i + 1) t_i\).

贪心地考虑, 由于我们要使得原式最大, \(\sum_{i = 1}^n l_i\) 为定值, 那么就需要使得后面那坨最小.
容易发现\(t_i\) 从小到大排序的时候整体最小, 所以第一个输出的答案就显而易见了.

考虑修改, 用树状数组维护即可.

#include "iostream"
#include "algorithm"

using namespace std;

#define int long long

template <class T>
inline void read(T &x) {
    x = 0;
    char ch = getchar();
    while (ch < '0' or ch > '9')
        ch = getchar();
    while (ch >= '0' and ch <= '9')
        x = x * 10 + ch - 48, ch = getchar();
}

void print(int x) {
    if (x < 0)
        x = -x, putchar('-');
    if (x > 9)
        print(x / 10);
    putchar(x % 10 + '0');
}

#define pcn putchar('\n')

constexpr int N = 2e5 + 10;

int n, q, s1 = 0, s2 = 0;
int l[N], t[N], a[N];

class Binary_Indexed_Tree {
protected:
    int tr[N];
    #define lowbit(x) x & -x

public:
    void update(int x, int k) {
        while (x <= 2e5) {
            tr[x] += k;
            x += lowbit(x);
        }
    }
    int query(int x) {
        int ret = 0;
        while (x) {
            ret += tr[x];
            x -= lowbit(x);
        }
        return ret;
    }

} b1, b2;

void init() {
    read(n), read(q);
    for (int i = 1; i <= n; ++i) {
        read(l[i]), read(t[i]);
        s1 += l[i], a[i] = t[i];
        b1.update(t[i], 1);
        b2.update(t[i], t[i]);
    }
    sort(t + 1, t + n + 1);
    for (int i = 1; i <= n; ++i)
        s2 += (n - i + 1) * t[i];
    print(s1 - s2), pcn;
}

void calculate() {
    while (q--) {
        int r, _l, _t;
        read(r), read(_l), read(_t);
        s1 = s1 - l[r] + _l, l[r] = _l;
        s2 -= a[r] * (n - b1.query(a[r] - 1)) + b2.query(a[r] - 1);
        b1.update(a[r], -1), b2.update(a[r], -a[r]);
        a[r] = _t;
        b1.update(a[r], 1), b2.update(a[r], a[r]);
        s2 += a[r] * (n - b1.query(a[r] - 1)) + b2.query(a[r] - 1);
        print(s1 - s2), pcn;
    }
}

void solve() {
    init();
    calculate();
}

signed main() {
    solve();
    return 0;
}
posted @   Steven1013  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示