zoukankan      html  css  js  c++  java
  • HDU

    题意:

      长度为N的序列,初始时间戳为0,有M次操作。

      C l r d:代表区间[l, r]的数加d,当前时间戳加1.

      Q l r:代表输出当前时间戳内[l, r]的区间和.

      H l r t:代表输出时间戳为t时[l, r]的区间和.

      B t:代表把时间戳置为t.

    题解:

      先初始化一棵带lazy线段树,之后就是主席树的做法,查询就是线段树区间求和操作。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    using namespace std;
    const int maxn = 1e5+10;
    typedef long long ll;
    int n, m;
    int w[maxn];
    int tot, tim;
    int root[maxn];
    int l, r, t;
    char s[5];
    struct node {
        int l, r, lazy;
        ll sum;
    }tre[maxn*40];
    void build(int l, int r, int &x) {
        x = ++tot;
        tre[x].lazy = 0;
        if(l==r) {
            scanf("%lld", &tre[x].sum);
            return ;
        }
        int mid = l+r>>1;
        build(l, mid, tre[x].l);
        build(mid+1, r, tre[x].r);
        tre[x].sum = tre[tre[x].l].sum+tre[tre[x].r].sum;
        return ;
    }
    void update(int l, int r, int &x, int y, int ql, int qr, int val) {
        tre[++tot] = tre[y];
        tre[tot].sum += 1ll*(qr-ql+1)*val;
        x = tot;
        if(l==ql&&qr==r) {
            tre[x].lazy += val;
            return ;
        }
        int mid = l+r>>1;
        if(qr<=mid) update(l, mid, tre[x].l, tre[y].l, ql, qr, val);
        else if(ql>mid) update(mid+1, r, tre[x].r, tre[y].r, ql, qr, val);
        else {
            update(l, mid, tre[x].l, tre[y].l, ql, mid, val);
            update(mid+1, r, tre[x].r, tre[y].r, mid+1, qr, val);
        }
    }
    ll query(int l, int r, int x, int ql, int qr) {
        if(ql==l&&qr==r) return tre[x].sum;
        int mid = l+r>>1;
        ll res = 1ll*(qr-ql+1)*tre[x].lazy;
        if(qr<=mid) res += query(l, mid, tre[x].l, ql, qr);
        else if(ql>mid) res += query(mid+1, r, tre[x].r, ql, qr);
        else res += query(l, mid, tre[x].l, ql, mid)+query(mid+1, r, tre[x].r, mid+1, qr);
        return res;
    }
    int main() {
        int f = 0;
        while(~scanf("%d%d", &n, &m)) {
            if(f) puts("");
            f++;
            tim = tot = 0;
            build(1, n, root[0]);
            for(int i = 1; i <= m; i++) {
                scanf("%s", s);
                if(s[0]=='C') scanf("%d%d%d", &l, &r, &t), update(1, n, root[++tim], root[tim-1], l, r, t);
                if(s[0]=='Q') scanf("%d%d", &l, &r), printf("%lld
    ", query(1, n, root[tim], l, r));
                if(s[0]=='H') scanf("%d%d%d", &l, &r, &t), printf("%lld
    ", query(1, n, root[t], l, r));
                if(s[0]=='B') scanf("%d", &tim);
            }
        }
    }
    View Code
  • 相关阅读:
    win2008服务器信任问题
    切换cmd的目录
    c#后的完整cookie
    c#网络编程-第一章
    c#访问mysql数据库
    标准库hashlib模块
    标准库ConfigParser模块
    标准库shutil
    标准库 xml
    标准库shelve
  • 原文地址:https://www.cnblogs.com/Pneuis/p/8993014.html
Copyright © 2011-2022 走看看