zoukankan      html  css  js  c++  java
  • Comet OJ

    题目链接:

    题意:有两个操作

    操作1:给出n个操作,将区间为l到r的数字改为x

    操作2:给出q个操作,输出进行了操作1中的第x到x+y-1操作后的结果

    解法:

    把询问离线,按照r从小到大排序

    每次询问的时候,用珂朵莉树推平区间

    求和,这个我们用树状数组维护即可

    树状数组求出>=l的和

    #include <bits/stdc++.h>
    #define IT set<node>::iterator
    using namespace std;
    typedef long long ll;
    const int M = 5e5 + 10;
    int n, m, q;
    ll anss[M], bit[M];
    struct node{
        int l, r, w;
        mutable ll v;
        bool operator < (const node &rhs) const {
            return l < rhs.l;
        }
    };
    struct note{
        int l, r, id;
        ll v;
    }a[M], b[M];
    set <node> s;
    void add(int i, ll x) {
        if(!i) return;
        while(i <= m) {
            bit[i] += x;
            i += i & (-i);
        }
    }
    ll query(int i) {
        ll ans = 0;
        while(i) {
            ans += bit[i];
            i -= i & (-i);
        }
        return ans;
    }
    IT split(int pos) {
        IT it = s.lower_bound(node{pos});
        if(it != s.end() && it->l == pos) return it;
        it--;
        int L = it->l, R = it->r, w = it->w;
        ll V = it->v;
        s.erase(it);
        s.insert(node{L, pos - 1, w, V});
        return s.insert(node{pos, R, w, V}).first;
    }
    void modify(int l, int r, int w, ll v) {
        IT it2 = split(r + 1), it1 = split(l), it3 = it1;
        for(; it1 != it2; it1++) add(it1->w, -(it1->v) * (it1->r - it1->l + 1));
        s.erase(it3, it2);
        s.insert(node{l, r, w, v});
        add(w, v * (ll)(r - l + 1));
    }
    bool cmp(note p, note q) {
        return p.r < q.r;
    }
    int main(){
        scanf("%d%d%d", &m, &n, &q);
        s.insert(node{1, n, 0, 0});
        for(int i = 1; i <= m; i++) scanf("%d%d%lld", &a[i].l, &a[i].r, &a[i].v);
        for(int i = 1; i <= q; i++) scanf("%d%d", &b[i].l, &b[i].r), b[i].id = i;
        sort(b + 1, b + q + 1, cmp);
        int j = 1;
        for(int i = 1; i <= q; i++) {
            while(j <= b[i].r && j <= m) modify(a[j].l, a[j].r, j, a[j].v), j++;
            //printf("anss %lld %lld
    ", query(n), query(b[i].l - 1));
            anss[b[i].id] = query(m) - query(b[i].l - 1);
        }
        for(int i = 1; i <= q; i++) printf("%lld
    ", anss[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    更新Centos 8 内核
    Docker安装
    微服务学习实战笔记 4.1-系统部署篇-Centos 8 下 安装配置K8S
    安装supervisor
    微服务学习实战笔记 4.2-系统部署篇-搭建 Harbor 镜像仓库服务器
    SRS流媒体服务器安装
    微服务学习实战笔记 1.1-系统架构篇-技术选型
    .Net Core 3.0 使用 Serilog 把日志记录到 SqlServer
    IdentityServer4 自定义授权模式
    IdentityServer4 保护.net framework webapi
  • 原文地址:https://www.cnblogs.com/linglinga/p/12031153.html
Copyright © 2011-2022 走看看