【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;
    
} 
原文地址:https://www.cnblogs.com/evenbao/p/9196412.html