[模板]線段樹2
阿新 • • 發佈:2018-02-18
pac src style getchar bsp .org img color lose https://www.luogu.org/problemnew/show/P3373
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #define lson (o<<1) 7 #define rson (o<<1|1) 8 using namespace std; 9 const int N = 100010View Code; 10 11 int a[N], n, m, p; 12 13 inline int read() { 14 register int n, ch; 15 n = 0, ch = getchar(); 16 while (!isdigit(ch)) ch = getchar(); 17 while (isdigit(ch)) n = (n << 3) + (n << 1) + ch - ‘0‘, ch = getchar(); 18 return n; 19 } 20 struct Node{21 long long sum, add, mul; 22 }t[N<<2]; 23 inline void pushup(int o){t[o].sum=(t[lson].sum+t[rson].sum)%p;} 24 inline void muldown(int o, int l, int r){ 25 int ls = lson, rs = rson, mid = (l+r)>>1; 26 t[ls].mul=(t[ls].mul*t[o].mul)%p; 27 t[rs].mul=(t[rs].mul*t[o].mul)%p;28 t[ls].add=(t[ls].add*t[o].mul)%p; 29 t[rs].add=(t[rs].add*t[o].mul)%p; 30 t[ls].sum=(t[ls].sum*t[o].mul)%p; 31 t[rs].sum=(t[rs].sum*t[o].mul)%p; 32 t[o].mul=1; 33 } 34 35 inline void adddown(int o, int l, int r){ 36 int ls = lson, rs = rson, mid = (l+r)>>1; 37 t[ls].add=(t[ls].add+t[o].add)%p; 38 t[rs].add=(t[rs].add+t[o].add)%p; 39 t[ls].sum=(t[ls].sum+(mid-l+1)*t[o].add)%p; 40 t[rs].sum=(t[rs].sum+(r-mid)*t[o].add)%p; 41 t[o].add=0; 42 } 43 inline void build(int o, int l, int r){ 44 t[o].mul=1; 45 t[o].add=0; 46 if (l==r){t[o].sum=a[l];return ;} 47 int mid = (l+r)>>1; 48 build(lson,l,mid), build(rson,mid+1,r); 49 pushup(o); 50 } 51 52 inline void secadd(int o,int l, int r, int ql, int qr, int v){ 53 if (ql<=l&&r<=qr){ 54 t[o].add=(t[o].add+v)%p; 55 t[o].sum=(t[o].sum+(r-l+1)*v)%p; 56 return ; 57 } 58 if (t[o].mul!=1) muldown(o,l,r); 59 if (t[o].add) adddown(o,l,r); 60 int mid = (l+r)>>1; 61 if (ql<=mid) secadd(lson,l,mid,ql,qr,v); 62 if (qr>mid) secadd(rson,mid+1,r,ql,qr,v); 63 pushup(o); 64 } 65 inline void secmul(int o, int l, int r, int ql, int qr, int v){ 66 if (ql<=l&&r<=qr){ 67 t[o].mul=(t[o].mul*v)%p; 68 t[o].add=(t[o].add*v)%p; 69 t[o].sum=(t[o].sum*v)%p; 70 return ; 71 } 72 if (t[o].mul!=1) muldown(o,l,r); 73 if (t[o].add) adddown(o,l,r); 74 int mid = (l+r)>>1; 75 if (ql<=mid) secmul(lson,l,mid,ql,qr,v); 76 if (qr>mid) secmul(rson,mid+1,r,ql,qr,v); 77 pushup(o); 78 } 79 inline long long query(int o,int l, int r, int ql, int qr){ 80 if (ql<=l&&r<=qr) return t[o].sum%p; 81 if (t[o].mul!=1) muldown(o,l,r); 82 if (t[o].add) adddown(o,l,r); 83 int mid = (l+r)>>1; 84 long long ans=0; 85 if (ql<=mid) ans+=query(lson,l,mid,ql,qr); 86 if (qr>mid) ans+=query(rson,mid+1,r,ql,qr); 87 return ans%p; 88 } 89 90 91 int main(void){ 92 n=read(), m=read(); p = read(); 93 for(register int i = 1; i <= n; ++i) a[i] = read(); 94 build(1,1,n); 95 while(m--){ 96 register int bs = read(), x = read(), y = read(), k; 97 if (bs == 1){k = read(); secmul(1,1,n,x,y,k);} 98 else if (bs == 2){k = read(); secadd(1,1,n,x,y,k);} 99 else printf("%lld\n", query(1,1,n,x,y)); 100 } 101 return 0; 102 }
[模板]線段樹2