• 【JSOI 2014】序列维护


    【题目链接】

               点击打开链接

    【算法】

             线段树

             注意标记下传

    【代码】

              

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 500000
    
    typedef long long LL;
    
    struct SegTreeNode {
        LL l,r,sum,lazya,lazyb;    
    }tree[MAXN+10];
    
    LL i,N,P,Q,l,r,x,opt;
    LL a[MAXN+10];
    
    template <typename T> void read(T &x) {
        LL f=1; char c = getchar(); x=0;
        for (; !isdigit(c); c = getchar()) { if (c=='-') f=-1; }
        for (; isdigit(c); c = getchar()) x=x*10+c-'0';
        x*=f;
    }
    
    inline void write(LL x) {
        if (x < 0) {
            putchar('-');
            x = -x;
        }
        if (x / 10 > 0) write(x/10);
        putchar(x%10+'0');    
    } 
    
    inline void pushup(LL index) {
        tree[index].sum = (tree[index*2].sum + tree[index*2+1].sum) % P;    
    }
    
    inline void pushdown(LL index) { 
        tree[index*2].sum = (tree[index*2].sum * tree[index].lazya + tree[index].lazyb * (tree[index*2].r - tree[index*2].l + 1)) % P;
        tree[index*2+1].sum = (tree[index*2+1].sum * tree[index].lazya + tree[index].lazyb * (tree[index*2+1].r - tree[index*2+1].l + 1)) % P;
        tree[index*2].lazya = (tree[index*2].lazya * tree[index].lazya) % P;
        tree[index*2+1].lazya = (tree[index*2+1].lazya * tree[index].lazya) % P;
        tree[index*2].lazyb = (tree[index*2].lazyb * tree[index].lazya + tree[index].lazyb) % P;
        tree[index*2+1].lazyb = (tree[index*2+1].lazyb * tree[index].lazya + tree[index].lazyb) % P;
        tree[index].lazya = 1; tree[index].lazyb = 0;
    }
    
    inline void build(LL index,LL l,LL r) {
        LL mid;
        tree[index].l = l;
        tree[index].r = r;
        tree[index].lazya = 1; 
        if (l == r) tree[index].sum = a[l] % P;
        else {
            mid = (l + r) >> 1;
            build(index*2,l,mid);
            build(index*2+1,mid+1,r);
            pushup(index);
        }    
    }
    
    inline void changea(int index,int l,int r,int x) {
        LL mid;
        pushdown(index);
        if ((tree[index].l == l) && (tree[index].r == r)) {
            tree[index].sum = tree[index].sum * x % P; 
            tree[index].lazya = (tree[index].lazya * x) % P;  
            tree[index].lazyb = (tree[index].lazyb * x) % P;
        }else {
                if (tree[index].l == tree[index].r) return;
            mid = (tree[index].l + tree[index].r) >> 1;
               if (r <= mid) changea(index*2,l,r,x);
            else if (l >= mid + 1) changea(index*2+1,l,r,x);
            else {
                changea(index*2,l,mid,x);
                changea(index*2+1,mid+1,r,x);
            }
            pushup(index);
        } 
    }
    
    inline void changeb(LL index,LL l,LL r,LL x) {
        LL mid;
        pushdown(index);
        if ((tree[index].l == l) && (tree[index].r == r)) {
            tree[index].sum = (tree[index].sum + x * (tree[index].r - tree[index].l + 1)) % P;
            tree[index].lazyb = (tree[index].lazyb + x) % P;  
        }else {
                if (tree[index].l == tree[index].r) return;
            mid = (tree[index].l + tree[index].r) >> 1;
            if (r <= mid) changeb(index*2,l,r,x);
            else if (l >= mid + 1) changeb(index*2+1,l,r,x);
            else {
                if (tree[index].l == tree[index].r) return;
                changeb(index*2,l,mid,x);
                changeb(index*2+1,mid+1,r,x);
            }
            pushup(index);
        } 
    }
    
    inline LL query(LL index,LL l,LL r) {
        LL mid;
        pushdown(index);
        if ((tree[index].l == l) && (tree[index].r == r)) return tree[index].sum;  
        else {
                if (tree[index].l == tree[index].r) return 0;
            mid = (tree[index].l + tree[index].r) >> 1;
            if (r <= mid) return query(index*2,l,r);
            else if (l >= mid + 1) return query(index*2+1,l,r);
            else return (query(index*2,l,mid) + query(index*2+1,mid+1,r)) % P;
        }
    }
    
    int main() {
        
        read(N); read(P);
        
        for (i = 1; i <= N; i++) read(a[i]);
        
        build(1,1,N);
        
        read(Q);
        
        while (Q--) {
            read(opt);
            if (opt == 1) {
                read(l); read(r); read(x);
                changea(1,l,r,x);
            }else if (opt == 2) {
                read(l); read(r); read(x);
                changeb(1,l,r,x);
            }else {
                read(l); read(r);
                write(query(1,l,r));
                puts("");    
            }
        }    
        
        return 0;
        
    } 
  • 相关阅读:
    WinForm容器内控件批量效验是否同意为空?设置是否仅仅读?设置是否可用等方法分享
    EF的CRUD
    SICP 习题 (1.41)解题总结
    陈光标挽救纽约穷人背后有何玄机?
    poj 1276 Cash Machine(多重背包)
    vue的生命周期
    vue mounted组件的使用
    babel-polyfill的几种使用方式
    可拖拽排序的vue组件
    import、export 和 export default
  • 原文地址:https://www.cnblogs.com/evenbao/p/9196412.html
Copyright © 2020-2023  润新知