• ACWing 268 流星


    Problem


    Solution

    Thinking 1

    修改操作显然是区间加,可以整体二分。
    但是如果这个区间按照国家来看的话,就不是连续的了,然道要(nlog{n})单点修改?不必,反过来,把每个国家的基站存起来,询问时直接每个基站的贡献相加。

    Thinking 2

    每个基站的贡献可以用单点查询得到,BIT维护。

    Thinking 3

    然后变成了整体二分板子。

    # include <bits/stdc++.h>
    using namespace std;
    # define int long long 
    const int N = 3e5 + 5;
    int n,m,k;
    vector <int> g[N];
    int p[N];
    int a[N],ans[N];
    int lc[N],rc[N];
    template <typename T> void read(T &x) {int w = 1;x = 0; char ch = getchar(); while(!isdigit(ch)) {if(ch == '-') w = -1; ch = getchar();} while(isdigit(ch)){x = x * 10 + ch - '0'; ch = getchar();} x *= w;}
    
    struct node
    {
        int l,r,a;
        node() {}
        node(int _l,int _r,int _a) : l(_l),r(_r),a(_a) {}
    }A[N];
    struct BIT
    {
        int T[N];
        int lowbit(int x) {return x & (-x);}
        void add(int x,int d)
        {
            while(x <= m)
            {
                T[x] += d,x += lowbit(x);
            }
            return;
        }
        int query(int x)
        {
            int total = 0;
            while(x)
            {
                total += T[x];x -= lowbit(x);
            }
            return total;
        }
        void update(int l,int r,int d)
        {
            add(l,d),add(r + 1,-d);
            return;
        }
    }T;
    void dfs(int L,int R,int l,int r)
    {
        if(l > r) return;
        // printf("L = %lld,R = %lld,l = %lld,r = %lld
    ",L,R,l,r);
        if(L == R)
        {
            for(int i = l; i <= r; i++) ans[a[i]] = L;
            return;
        }
        int mid = (L + R) >> 1,lt = 0,rt = 0;
        for(int i = L; i <= mid; i++)
        {   
            if(A[i].l <= A[i].r) T.add(A[i].l,A[i].a),T.add(A[i].r + 1,-A[i].a);
            else T.add(A[i].l,A[i].a),T.add(1,A[i].a),T.add(A[i].r + 1,-A[i].a);
            // if(A[i].l <= A[i].r) T.update(A[i].l,A[i].r,A[i].a);
            // else T.update(A[i].l,m,A[i].a),T.update(1,A[i].r,A[i].a);
        }
        for(int i = l; i <= r; i++)
        {
            int cur = 0;
            for(int j = 0; j < (int)g[a[i]].size(); j++)
            {
                cur += T.query(g[a[i]][j]);
                if(cur >= p[a[i]]) break;
            }
            if(cur >= p[a[i]]) lc[++lt] = a[i];
            else rc[++rt] = a[i],p[a[i]] -= cur;
        }
        for(int i = L; i <= mid; i++)
        {
            if(A[i].l <= A[i].r) T.add(A[i].l,-A[i].a),T.add(A[i].r + 1,A[i].a);
            else T.add(A[i].l,-A[i].a),T.add(1,-A[i].a),T.add(A[i].r + 1,A[i].a);
            // if(A[i].l <= A[i].r) T.update(A[i].l,A[i].r,-A[i].a);
            // else T.update(A[i].l,m + 1,A[i].a),T.update(1,A[i].r,-A[i].a);
        }
        for(int i = 1; i <= lt; i++) a[l + i - 1] = lc[i];
        for(int i = 1; i <= rt; i++) a[l + lt + i - 1] = rc[i];
        dfs(L,mid,l,l + lt - 1);
        dfs(mid + 1,R,l + lt,r);
        return; 
    }
    signed main(void)
    {
        read(n),read(m);
        for(int i = 1; i <= m; i++)
        {
            int x;
            read(x);
            g[x].push_back(i);
        }
        for(int i = 1; i <= n; i++)
        {
            read(p[i]);
            a[i] = i;
        }
        read(k);
        for(int i = 1; i <= k; i++)
        {
            int l,r,a;
            read(l),read(r),read(a);
            A[i] = node(l,r,a);
        }
        A[k + 1] = node(1,m,1e9 + 7);
        dfs(1,k + 1,1,n);
        for(int i = 1; i <= n; i++)
        {
            if(ans[i] > k) printf("NIE
    ");
            else printf("%lld
    ",ans[i]);
        }
        return 0;
    }
    
  • 相关阅读:
    【洛谷P4708】—画画(Burnside引理)
    【HDU 6087】—Rikka with Sequence(可持久化平衡树)
    【HDU 6087】—Rikka with Sequence(可持久化平衡树)
    【Codeforces 643G】—Choosing Ads(线段树)
    【Codeforces 643G】—Choosing Ads(线段树)
    less sass学习总结(——待续哦——)
    网站常识
    网站发布流程
    解惑 和 遇到的问题
    页面无法访问 css文件加载问题
  • 原文地址:https://www.cnblogs.com/luyiming123blog/p/14826259.html
Copyright © 2020-2023  润新知