|
- #include <algorithm>
- #include <iostream>
- #include <cmath>
- #include <cstring>
- #include <map>
- #include <string>
- #include <vector>
- #include <queue>
- #include <stack>
- #include <cstdio>
- #include <cstdlib>
- using namespace std;
- const int N = 2e5 + 10;
- typedef long long LL;
- LL sum[N * 4]= {0}, tag_add[N * 4]= {0}, tag_mul[N * 4]= {0},a[N],mo;
- void build(int l, int r, int o)
- {
- if(l == r)
- {
- sum[o] = a[l];
- tag_add[o] = 0,tag_mul[o]=1;
- return ;
- }
- int mid = (l + r) >> 1;
- build(l, mid, o * 2);
- build(mid + 1, r, o << 1 | 1);
- sum[o] = (sum[o << 1] + sum[o << 1 | 1])%mo;
- tag_add[o] = 0,tag_mul[o]=1;
- return ;
- }
- void update_mul(int L, int R, LL mul, int l, int r, int o)
- {
- if(L <= l && r <= R)
- {
- (sum[o] *= mul)%=mo;
- (tag_mul[o] *= mul)%=mo;
- (tag_add[o] *= mul)%=mo;
- return ;
- }
- int mid = (l + r) >> 1;
- if(tag_mul[o]!=1)
- {
- (sum[o << 1] *= tag_mul[o])%=mo;
- (tag_mul[o << 1] *= tag_mul[o])%=mo;
- (tag_add[o << 1] *= tag_mul[o])%=mo;
- (sum[o << 1|1] *= tag_mul[o])%=mo;
- (tag_mul[o << 1|1] *= tag_mul[o])%=mo;
- (tag_add[o << 1|1] *= tag_mul[o])%=mo;
- tag_mul[o] = 1;
- }
- if(tag_add[o])
- {
- (sum[o << 1] += tag_add[o] * (mid - l + 1))%=mo;
- (tag_add[o << 1] += tag_add[o])%=mo;
- (sum[o << 1|1] += tag_add[o] * (r - mid))%=mo;
- (tag_add[o << 1|1] += tag_add[o])%=mo;
- tag_add[o] = 0;
- }
- if(L <= mid) update_mul(L, R, mul, l, mid, o << 1);
- if(R > mid) update_mul(L, R, mul, mid + 1, r, o << 1 | 1);
- sum[o] = (sum[o << 1] + sum[o << 1 | 1])%mo;
- }
- void update_add(int L, int R, LL add, int l, int r, int o)
- {
- if(L <= l && r <= R)
- {
- (sum[o] += add * (r - l + 1))%=mo;
- (tag_add[o] += add)%=mo;
- return ;
- }
- int mid = (l + r) >> 1;
- if(tag_mul[o]!=1)
- {
- (sum[o << 1] *= tag_mul[o])%=mo;
- (tag_mul[o << 1] *= tag_mul[o])%=mo;
- (tag_add[o << 1] *= tag_mul[o])%=mo;
- (sum[o << 1|1] *= tag_mul[o])%=mo;
- (tag_mul[o << 1|1] *= tag_mul[o])%=mo;
- (tag_add[o << 1|1] *= tag_mul[o])%=mo;
- tag_mul[o] = 1;
- }
- if(tag_add[o])
- {
- (sum[o << 1] += tag_add[o] * (mid - l + 1))%=mo;
- (tag_add[o << 1] += tag_add[o])%=mo;
- (sum[o << 1|1] += tag_add[o] * (r - mid))%=mo;
- (tag_add[o << 1|1] += tag_add[o])%=mo;
- tag_add[o] = 0;
- }
- if(L <= mid) update_add(L, R, add, l, mid, o << 1);
- if(R > mid) update_add(L, R, add, mid + 1, r, o << 1 | 1);
- sum[o] = (sum[o << 1] + sum[o << 1 | 1])%mo;
- }
- LL query(int L, int R, int l, int r, int o)
- {
- if(L <= l && r <= R)
- {
- return sum[o];
- }
- int mid = (l + r) >> 1;
- if(tag_mul[o]!=1)
- {
- (sum[o << 1] *= tag_mul[o])%=mo;
- (tag_mul[o << 1] *= tag_mul[o])%=mo;
- (tag_add[o << 1] *= tag_mul[o])%=mo;
- (sum[o << 1|1] *= tag_mul[o])%=mo;
- (tag_mul[o << 1|1] *= tag_mul[o])%=mo;
- (tag_add[o << 1|1] *= tag_mul[o])%=mo;
- tag_mul[o] = 1;
- }
- if(tag_add[o])
- {
- (sum[o << 1] += tag_add[o] * (mid - l + 1))%=mo;
- (tag_add[o << 1] += tag_add[o])%=mo;
- (sum[o << 1|1] += tag_add[o] * (r - mid))%=mo;
- (tag_add[o << 1|1] += tag_add[o])%=mo;
- tag_add[o] = 0;
- }
- LL ans = 0;
- if(L <= mid) ans += query(L, R, l, mid, o << 1);
- if(R > mid) ans += query(L, R, mid + 1, r, o << 1 | 1);
- return ans%mo;
- }
- int main()
- {
- int n, m;
- scanf("%d %d %lld", &n, &m,&mo);
- for(int i=1; i<=n; i++)
- scanf("%lld", &a[i]);
- build(1, n, 1);
- while(m --)
- {
- int op;
- scanf("%d", &op);
- if(op == 1)
- {
- int l, r;
- LL x;
- scanf("%d %d %lld", &l, &r, &x);
- update_mul(l, r, x, 1, n, 1);
- }
- else if(op == 2)
- {
- int l, r;
- LL x;
- scanf("%d %d %lld", &l, &r, &x);
- update_add(l, r, x, 1, n, 1);
- }
- else
- {
- int l, r;
- scanf("%d %d", &l, &r);
- printf("%lld\n", query(l, r, 1, n, 1));
- }
- }
- }
复制代码 |
|