1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef long long ll; 7 int n , m; 8 ll mod; 9 int num[100003]; 10 struct node 11 { 12 ll sum , add , mul; 13 }tree[100003 << 2]; 14 void update(int p) 15 { 16 tree[p].sum = (tree[p << 1].sum + tree[p << 1 | 1].sum) % mod; 17 } 18 void down(int p , int l , int r) 19 { 20 int mid = (l + r) >> 1; 21 tree[p << 1].sum = ( tree[p << 1].sum * tree[p].mul + tree[p].add * (mid - l + 1) ) % mod; 22 tree[p << 1 | 1].sum = ( tree[p << 1 | 1].sum * tree[p].mul + tree[p].add * (r - mid) ) % mod; 23 tree[p << 1].mul = (tree[p << 1].mul * tree[p].mul) % mod; 24 tree[p << 1 | 1].mul = (tree[p << 1 | 1].mul * tree[p].mul) % mod; 25 tree[p << 1].add = (tree[p].mul * tree[p << 1].add + tree[p].add) % mod; 26 tree[p << 1 | 1].add = (tree[p].mul * tree[p << 1 | 1].add + tree[p].add) % mod; 27 tree[p].mul = 1 , tree[p].add = 0; 28 } 29 void Build(int l , int r , int p) 30 { 31 tree[p].add = 0 ,tree[p].mul = 1; 32 if(l == r) 33 { 34 tree[p].sum = num[l]; 35 return; 36 } 37 int mid = (l + r) >> 1; 38 Build(l , mid , p << 1); 39 Build(mid + 1 , r , p << 1 | 1); 40 update(p); 41 } 42 void Mul(int l , int r , int ll , int rr , int p , int k) 43 { 44 if(ll >= l && rr <= r) 45 { 46 tree[p].mul = tree[p].mul * k % mod; 47 tree[p].add = tree[p].add * k % mod; 48 tree[p].sum = tree[p].sum * k % mod; 49 return; 50 } 51 down(p , ll , rr); 52 int mid = (ll + rr) >> 1; 53 if(mid >= l) 54 Mul(l , r , ll , mid , p << 1 , k); 55 if(mid < r) 56 Mul(l , r , mid + 1 , rr , p << 1 | 1 , k); 57 update(p); 58 } 59 void Add(int l , int r , int ll , int rr , int p , int k) 60 { 61 if(ll >= l && rr <= r) 62 { 63 tree[p].add = (tree[p].add + k) % mod; 64 tree[p].sum = (tree[p].sum + (rr - ll + 1) * k) % mod; 65 return; 66 } 67 down(p , ll , rr); 68 int mid = (ll + rr) >> 1; 69 if(mid >= l) 70 Add(l , r , ll , mid , p << 1 , k); 71 if(mid < r) 72 Add(l , r , mid + 1 , rr , p << 1 | 1 , k); 73 update(p); 74 } 75 ll Query(int l , int r , int ll , int rr , int p) 76 { 77 long long ans = 0; 78 if(ll >= l && rr <= r) 79 return tree[p].sum; 80 down(p , ll , rr); 81 int mid = (ll + rr) >> 1; 82 if(mid >= l) 83 ans = (ans + Query(l , r , ll , mid , p << 1)) % mod; 84 if(mid < r) 85 ans = (ans + Query(l , r , mid + 1 , rr , p << 1 | 1)) % mod; 86 update(p); 87 return ans; 88 } 89 int main() 90 { 91 int opt , l , r , k; 92 scanf("%d%d%lld" , &n , &m , &mod); 93 for(int i = 1; i <= n; i++) 94 scanf("%d" , &num[i]); 95 Build(1 , n , 1); 96 for(int i = 1; i <= m; i++) 97 { 98 scanf("%d" , &opt); 99 if(opt == 1) 100 { 101 scanf("%d%d%d" , &l , &r , &k); 102 Mul(l , r , 1 , n , 1 , k); 103 } 104 if(opt == 2) 105 { 106 scanf("%d%d%d" , &l , &r , &k); 107 Add(l , r , 1 , n , 1 , k); 108 } 109 if(opt == 3) 110 { 111 scanf("%d%d" , &l , &r); 112 printf("%lld\n" , Query(l , r , 1 , n , 1) % mod); 113 } 114 } 115 return 0; 116 }
线段树