• LG 题解 SP10264 METEORS


    题目传送

    双倍经验

    更好的阅读体验?

    前置芝士

    • 整体二分
    • 树状数组

    Solution

    一道经典的整体二分题目。

    一个显然的想法是二分操作次数。

    假设二分到了 ([l,r]) 这段操作区间,下一个分解点为 (mid)

    发现陨石雨的实质是区间加,那么我们可以在树状数组上差分。

    先执行所有陨石雨操作,直接把在 ([l,mid]) 区间的所有陨石雨的贡献统计。

    然后遍历答案在 ([l,r]) 区间的每个国家,暴力统计每个国家能收集到的陨石即可,树状数组单点查询操作。(当然你需要用 vector 预处理每个国家能收集那几个地方的陨石)

    如果能够满足,就把它放进 ([l,mid]) 对应的序列中,否则减去这一次的贡献,把它放进 ([mid+1,r]) 对应的序列中。

    不断递归下去即可。

    直到 (l=r) 就可以确定答案了。

    对于判断无解的时候,我们可以直接从 ([1,Q+1]) 开始二分((Q) 表示有 (Q) 次陨石雨),那么最后答案为 (Q+1) 的国家即为找不到答案的国家。

    因为轨道是个环形,所以一个小 Trick 是把 (l>r) 的操作拆成两部分。但在双倍经验那道题上有点卡空间,只在需要的地方开 unsigned long long 就行。

    你问我为什么要开 unsigned long long?因为极限数据下会爆 long long

    剩下的细节看代码吧。

    Code

    /*
    Work by: Suzt_ilymics
    Problem: 不知名屑题
    Knowledge: 垃圾算法
    Time: O(能过)
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #define LL unsigned long long
    #define orz cout<<"lkp AK IOI!"<<endl
    
    using namespace std;
    const int MAXN = 3e5+50;
    const int INF = 1e9+7;
    const int mod = 1e9+7;
    
    struct node {
        int l, r, c, id, type;
    }q[MAXN*3], q1[MAXN*3], q2[MAXN*3];
    
    int n, m, Q, tot = 0;
    int p[MAXN], ans[MAXN];
    vector<int> fr[MAXN];
    
    int read(){
        int s = 0, f = 0;
        char ch = getchar();
        while(!isdigit(ch))  f |= (ch == '-'), ch = getchar();
        while(isdigit(ch)) s = (s << 1) + (s << 3) + ch - '0' , ch = getchar();
        return f ? -s : s;
    }
    
    namespace BIT {
        LL sum[MAXN];
        int lb(int x) { return x&-x; }
        void Modify(int pos, int val) { for( ; pos <= m; pos += lb(pos)) sum[pos] += val; }
        LL Query(int pos) { LL res = 0; for( ; pos; pos -= lb(pos)) res += sum[pos]; return res; }
    }
    
    void Solve(int l, int r, int ql, int qr) {
        if(ql > qr) return ;
        if(l == r) {
            for(int i = ql; i <= qr; ++i) if(q[i].type) ans[q[i].id] = l;
            return ;
        }
        int mid = (l + r) >> 1, cnt1 = 0, cnt2 = 0;
        for(int i = ql; i <= qr; ++i) {
            if(!q[i].type) {
                if(q[i].id <= mid) {
                    BIT::Modify(q[i].l, q[i].c);
                    BIT::Modify(q[i].r+1, -q[i].c);
                    q1[++cnt1] = q[i];
                } else {
                    q2[++cnt2] = q[i];
                }
            } else {
                LL sum = 0;
                for(int j = 0, M = fr[q[i].id].size(); j < M; ++j) sum += BIT::Query(fr[q[i].id][j]);
                if(sum >= q[i].c) {
                    q1[++cnt1] = q[i];
                } else {
                    q[i].c -= sum;
                    q2[++cnt2] = q[i];
                }
            }
        }
        for(int i = 1; i <= cnt1; ++i) if(!q1[i].type) BIT::Modify(q1[i].l, -q1[i].c), BIT::Modify(q1[i].r+1, q1[i].c);
        for(int i = 1; i <= cnt1; ++i) q[ql + i - 1] = q1[i];
        for(int i = 1; i <= cnt2; ++i) q[ql + cnt1 + i - 1] = q2[i];
        Solve(l, mid, ql, ql + cnt1 - 1);
        Solve(mid + 1, r, ql + cnt1, ql + cnt1 + cnt2 - 1);
    }
    
    signed main()
    {
        n = read(), m = read();
        for(int i = 1; i <= m; ++i) fr[read()].push_back(i);
        for(int i = 1; i <= n; ++i) p[i] = read();
        Q = read();
        for(int i = 1, l, r, v; i <= Q; ++i) {
            l = read(), r = read(), v = read();
            if(l <= r) q[++tot] = (node){l, r, v, i, 0};
            else q[++tot] = (node){1, r, v, i, 0}, q[++tot] = (node){l, m, v, i, 0};
        }
        for(int i = 1; i <= n; ++i) q[++tot] = (node){0, 0, p[i], i, 1};
        Solve(1, Q + 1, 1, tot);
        for(int i = 1; i <= n; ++i) ans[i] <= Q ? printf("%d
    ", ans[i]) : puts("NIE");
        return 0;
    }
    
    
  • 相关阅读:
    Apache Commons CLI命令行启动
    《三体1——地球往事》—— 读后总结
    《鬼谷子的局4》 —— 读后总结
    Microsoft Visual C++ 2017 Redistributable
    Navicat Premium 12安装与激活(亲测已成功激活)
    如何从DOS命令窗口进行复制粘贴
    使用java写js中类似setTimeout的代码
    Spring @RestController、@Controller区别
    SpringBoot整合Swagger2
    git clone 报“The project you were looking for could not be found.”
  • 原文地址:https://www.cnblogs.com/Silymtics/p/15224320.html
Copyright © 2020-2023  润新知