【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; }