• SCUT


    https://scut.online/p/77
    线段树的一种奇怪的应用,暴力区间更新,每次update直接pushdown到底部,然后从维护底部。这样下次update的时候假如提前遇到底部就很快返回了。每个节点更新60次,单次更新nlogn。更新完毕之后每次update都是几乎一个log就返回了。

    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    
    const int MAXM = 100000;
    ll a[MAXM + 5];
    ll st[(MAXM << 2) + 5];
    bool zero[(MAXM << 2) + 5];
    
    const int mod = 1e9 + 7;
    
    inline void push_up(int o) {
        st[o] = (st[o << 1] + st[o << 1 | 1]) % mod;
        zero[o] = (zero[o << 1] && zero[o << 1 | 1]);
    }
    
    void build(int o, int l, int r) {
        if(l == r) {
            st[o] = a[l] % mod;
            zero[o] = (a[l] == 0);
        } else {
            int m = (l + r) >> 1;
            build(o << 1, l, m);
            build(o << 1 | 1, m + 1, r);
            push_up(o);
        }
    }
    
    void update(int o, int l, int r, int ql, int qr) {
        if(l == r) {
            a[l] >>= 1;
            st[o] = a[l] % mod;
            zero[o] = (a[l] == 0);
            return;
        }
        if(ql <= l && r <= qr && zero[o])
            return;
        int m = (l + r) >> 1;
        if(ql <= m)
            update(o << 1, l, m, ql, qr);
        if(qr >= m + 1)
            update(o << 1 | 1, m + 1, r, ql, qr);
        push_up(o);
    }
    
    ll query(int o, int l, int r, int ql, int qr) {
        if(ql <= l && r <= qr) {
            return st[o];
        } else {
            int m = (l + r) >> 1;
            ll ans = 0;
            if(ql <= m)
                ans = query(o << 1, l, m, ql, qr);
            if(qr >= m + 1)
                ans += query(o << 1 | 1, m + 1, r, ql, qr);
            return ans % mod;
        }
    }
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        int T, n, m;
        scanf("%d", &T);
        while(T--) {
            scanf("%d%d", &n, &m);
            for(int i = 1; i <= n ; ++i)
                scanf("%lld", &a[i]);
            build(1, 1, n);
            char op[20];
            int l, r;
            for(int i = 1; i <= m; ++i) {
                scanf("%s%d%d", op, &l, &r);
                if(op[0] == 'U') {
                    update(1, 1, n, l, r);
                } else {
                    printf("%lld
    ", query(1, 1, n, l, r));
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    HDU 5542 The Battle of Chibi (离散化+树状数组优化DP)
    UVaLive 7637 Balanced String (构造)
    ZOJ 3512 Financial Fraud (左偏树)
    HDU 1512 Monkey King (左偏树+并查集)
    POJ 2311 Cutting Game (博弈)
    POJ 2348 Euclid's Game (博弈)
    Gym 101142C CodeCoder vs TopForces (搜索)
    Gym
    Spring注解
    sql语句中的占位符?有什么作用
  • 原文地址:https://www.cnblogs.com/Yinku/p/11314143.html
Copyright © 2020-2023  润新知