1 条题解

  • 0
    @ 2026-3-17 19:48:00

    力竭,97分极限。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MAXN = 300005;
    
    int n, m, k;
    int owner[MAXN];
    ll need[MAXN];
    int ans[MAXN];
    vector<int> stations[MAXN];
    
    struct Event {
        int l, r;
        ll a;
    } rain[MAXN];
    
    ll bit[MAXN];
    void add(int x, ll v) {
        for (; x <= m; x += x & -x) bit[x] += v;
    }
    ll query(int x) {
        ll res = 0;
        for (; x; x -= x & -x) res += bit[x];
        return res;
    }
    void apply(int id, int coeff) {
        int l = rain[id].l, r = rain[id].r;
        ll a = rain[id].a * coeff;
        if (l <= r) {
            add(l, a);
            if (r + 1 <= m) add(r + 1, -a);
        } else {
            add(1, a);
            if (r + 1 <= m) add(r + 1, -a);
            add(l, a);
        }
    }
    
    void solve(int l, int r, vector<int>& ids) {
        if (l > r || ids.empty()) return;
        if (l == r) {
            for (int id : ids) ans[id] = l;
            return;
        }
        int mid = (l + r) >> 1;
        // 将[l, mid]的陨石雨加入
        for (int i = l; i <= mid; ++i) apply(i, 1);
        
        vector<int> leftIds, rightIds;
        for (int id : ids) {
            ll sum = 0;
            for (int pos : stations[id]) {
                sum += query(pos);
                if (sum >= need[id]) break;
            }
            if (sum >= need[id]) {
                leftIds.push_back(id);
            } else {
                rightIds.push_back(id);
            }
        }
        // 撤销[l, mid]的陨石雨
        for (int i = l; i <= mid; ++i) apply(i, -1);
        
        solve(l, mid, leftIds);
        // 注意:递归右半边时,需要将[l, mid]的陨石雨再次加入
        for (int i = l; i <= mid; ++i) apply(i, 1);
        solve(mid + 1, r, rightIds);
        // 撤销[l, mid]的陨石雨,恢复状态
        for (int i = l; i <= mid; ++i) apply(i, -1);
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= m; ++i) {
            int o;
            scanf("%d", &o);
            stations[o].push_back(i);
        }
        for (int i = 1; i <= n; ++i) {
            scanf("%lld", &need[i]);
        }
        scanf("%d", &k);
        for (int i = 1; i <= k; ++i) {
            scanf("%d%d%lld", &rain[i].l, &rain[i].r, &rain[i].a);
        }
        // 添加一场虚拟陨石雨,用于处理无解
        rain[k + 1] = {1, 1, 0};  // 注意:这里可以任意设置,因为雨量为0
        ++k;
        
        vector<int> allIds;
        for (int i = 1; i <= n; ++i) {
            allIds.push_back(i);
            ans[i] = k + 1;  // 初始化为k+1表示无解
        }
        
        solve(1, k, allIds);
        
        for (int i = 1; i <= n; ++i) {
            if (ans[i] == k) {  // 注意:k是虚拟陨石雨的编号
                printf("NIE\n");
            } else {
                printf("%d\n", ans[i]);
            }
        }
        return 0;
    }
    

    信息

    ID
    179
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    6
    已通过
    0
    上传者