zoukankan      html  css  js  c++  java
  • 2018 CCPC 吉林站 H Lovers

    2018 CCPC 吉林站 H Lovers

    传送门:https://www.spoj.com/problems/LIS2/en/

    题意:

    q次操作

    1.将第l~r个数的左边和和右边都加上一个数d, 使得这个数变成 (ds_id)的形式

    2.询问区间和

    题解:

    线段树题

    这个update操作不好维护,我们来冷静分析一下

    对于一个数x,他的长度为len,我们在他后面加上一个数d,那么他的长度就变成了len+1,这个数x就变成了(x*10+d)

    同理,在前面加上一个数,这个数x就变成了(d*10^{len(x)}+x)

    那么对于每次的update操作,我们需要更新,区间长度,区间和,左右添加的数,右边的标记每次要*10+d,左边的标记每次要加上len*val

    下推标记时

    要更新区间和,区间长度,左右标记,10的幂标记

    注意取模问题

    代码:

    #include <set>
    #include <map>
    #include <cmath>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    #define ls rt<<1
    #define rs rt<<1|1
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define bug printf("*********
    ")
    #define FIN freopen("input.txt","r",stdin);
    #define FON freopen("output.txt","w+",stdout);
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    #define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]
    "
    #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]
    "
    #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]
    "
    const int maxn = 3e5 + 5;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    LL sum1[maxn << 2];
    LL sum2[maxn << 2];
    LL lazy1[maxn << 2];
    LL lazy2[maxn << 2];
    LL lazylen[maxn << 2];
    void push_up(int rt) {
        sum1[rt] = (sum1[ls] + sum1[rs]) % mod;
        sum2[rt] = (sum2[ls] + sum2[rs]) % mod;
    }
    void build(int l, int r, int rt) {
        lazy1[rt] = lazy2[rt] = 0;
        lazylen[rt] = 1;
        sum1[rt] = r - l + 1;
        sum2[rt] = 0;
        if(l == r) return;
        int mid = (l + r) >> 1;
        build(lson);
        build(rson);
        push_up(rt);
    }
    void push_down(int l, int r, int rt) {
        if(lazylen[rt] > 1) {
            int mid = (l + r) >> 1;
    
            sum2[ls] = (lazy1[rt] % mod * sum1[ls] % mod * lazylen[rt] % mod +
                        sum2[ls] % mod * lazylen[rt] % mod +
                        lazy2[rt] % mod * 1LL * (mid - l + 1) % mod) % mod;
            sum2[rs] = (lazy1[rt] % mod * sum1[rs] % mod * lazylen[rt] % mod +
                        sum2[rs] % mod * lazylen[rt] % mod +
                        lazy2[rt] % mod * 1LL * (r - mid) % mod) % mod;
    
            sum1[ls] = (sum1[ls] % mod * lazylen[rt] % mod * lazylen[rt] % mod) % mod;
            sum1[rs] = (sum1[rs] % mod * lazylen[rt] % mod * lazylen[rt] % mod) % mod;
    
            lazy1[ls] = (lazy1[rt] % mod * lazylen[ls] % mod + lazy1[ls] % mod) % mod;
            lazy1[rs] = (lazy1[rt] % mod * lazylen[rs] % mod + lazy1[rs] % mod) % mod;
    
            lazy2[ls] = (lazy2[ls] % mod * lazylen[rt] % mod + lazy2[rt] % mod) % mod;
            lazy2[rs] = (lazy2[rs] % mod * lazylen[rt] % mod + lazy2[rt] % mod) % mod;
    
            lazylen[ls] = (lazylen[ls] % mod * lazylen[rt] % mod) % mod;
            lazylen[rs] = (lazylen[rs] % mod * lazylen[rt] % mod) % mod;
    
            lazylen[rt] = 1;
            lazy1[rt] = 0;
            lazy2[rt] = 0;
        }
    }
    void update(int L, int R, int val, int l, int r, int rt) {
        if(L <= l && r <= R) {
            sum2[rt] = (val % mod * sum1[rt] % mod * 10 % mod + sum2[rt] % mod * 10 % mod + (r - l + 1) % mod * val % mod) % mod;
            sum1[rt] = (sum1[rt] % mod * 100) % mod;
            lazy1[rt] = (lazylen[rt] % mod * val % mod + lazy1[rt] % mod) % mod;
            lazy2[rt] = (lazy2[rt] % mod * 10 % mod + val % mod) % mod;
            lazylen[rt] = (lazylen[rt] * 10) % mod;
            return;
        }
        int mid = (l + r) >> 1;
        push_down(l, r, rt);
        if(L <= mid) update(L, R, val, lson);
        if(R > mid) update(L, R, val, rson);
        push_up(rt);
    }
    LL query(int L, int R, int l, int r, int rt) {
        if(L <= l && r <= R) {
            return sum2[rt];
        }
        int mid = (l + r) >> 1;
        push_down(l, r, rt);
        LL ans = 0;
        if(L <= mid) ans = (ans + query(L, R, lson)) % mod;
        if(R > mid) ans = (ans + query(L, R, rson)) % mod;
        return ans % mod;
    }
    int main() {
    #ifndef ONLINE_JUDGE
        FIN
    #endif
        int T;
        int cas = 1;
        scanf("%d", &T);
        while(T--) {
            int n, m;
            scanf("%d%d", &n, &m);
            build(1, n, 1);
            printf("Case %d:
    ", cas++);
            while(m--) {
                char op[10];
                scanf("%s", op);
                if(op[0] == 'w') {
                    int l, r, d;
                    scanf("%d%d%d", &l, &r, &d);
                    update(l, r, d, 1, n, 1);
                    // debug2(n,m);
                } else {
                    int l, r;
                    scanf("%d%d", &l, &r);
                    printf("%lld
    ", query(l, r, 1, n, 1) % mod);
                }
            }
        }
        return 0;
    }
    
    每一个不曾刷题的日子 都是对生命的辜负 从弱小到强大,需要一段时间的沉淀,就是现在了 ~buerdepepeqi
  • 相关阅读:
    TdxGaugeControl
    TdxSkinController
    delphi TdxMemData 使用
    深入方法(16)- 方法的顺序
    深入方法(15)- 调用其他单元的函数
    深入方法(14)- 在TForm1 类内声明的方法
    深入方法(13)- 在 interface 区声明的方法
    深入方法(12)- implementation 区中的方法
    深入方法(11)- 参数前缀
    深入方法(10)- 默认参数
  • 原文地址:https://www.cnblogs.com/buerdepepeqi/p/11196394.html
Copyright © 2011-2022 走看看