这是算区间乘积的算法
#include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #define ll long long #define fori for(i=0;i<n;i++) #define fori1 for(i=1;i<=n;i++) using namespace std; const int maxn = 1e6 + 107; #define inf 0x3f3f3f3f const ll mod =1e9+7; ll p; struct node { ll l, r;//区间[l,r] ll add;//区间和的延时标记 ll mul;//区间乘积的延时标记 ll sum;//区间和 ll ji;//区间乘积 ll maxn; //区间最大值 ll minn; //区间最小值 }tree[maxn * 4 + 5];//一定要开到4倍多的空间 void pushup(ll rt) { tree[rt].sum = (tree[rt << 1].sum + tree[rt << 1 | 1].sum)%p; tree[rt].ji = tree[rt << 1].ji * tree[rt << 1 | 1].ji; tree[rt].maxn = max(tree[rt << 1].maxn, tree[rt << 1 | 1].maxn); tree[rt].minn = min(tree[rt << 1].minn, tree[rt << 1 | 1].minn); } void pushdown(ll rt) { if (tree[rt].add|| tree[rt].mul != 1) { tree[rt << 1].ji = (tree[rt << 1].ji*(tree[rt << 1].r - tree[rt << 1].l + 1) * tree[rt].add); tree[rt << 1 | 1].ji *= (tree[rt << 1 | 1].r - tree[rt << 1 | 1].l + 1) * tree[rt].add; tree[rt << 1].sum = (tree[rt << 1].sum*tree[rt].mul+(tree[rt << 1].r - tree[rt << 1].l + 1) * tree[rt].add)%p; tree[rt << 1 | 1].sum = (tree[rt << 1 | 1].sum * tree[rt].mul + (tree[rt << 1 | 1].r - tree[rt << 1 | 1].l + 1) * tree[rt].add)%p; tree[rt << 1].maxn += tree[rt].add; tree[rt << 1 | 1].maxn += tree[rt].add; tree[rt << 1].minn += tree[rt].add; tree[rt << 1 | 1].minn += tree[rt].add; tree[rt << 1].mul = (tree[rt << 1].mul * tree[rt].mul)%p; tree[rt << 1 | 1].mul = (tree[rt << 1 | 1].mul*tree[rt].mul)%p; tree[rt << 1].add = (tree[rt<<1].add*tree[rt].mul+ tree[rt].add)%p; tree[rt << 1 | 1].add = (tree[rt<<1|1].add* tree[rt].mul+tree[rt].add)%p; tree[rt].mul = 1; tree[rt].add = 0; } } void build(ll l, ll r, ll rt) { tree[rt].l = l; tree[rt].r = r; tree[rt].add = 0;//刚开始一定要清0 tree[rt].mul = 1;//刚开始一定要清1 if (l == r) { cin>>tree[rt].sum; tree[rt].minn = tree[rt].maxn = tree[rt].ji=tree[rt].sum; return; } ll mid = (l + r) >> 1; build(l, mid, rt << 1); build(mid + 1, r, rt << 1 | 1); pushup(rt); } void updata_plus(ll l, ll r, ll rt, ll val) { if (l <= tree[rt].l && r >= tree[rt].r) { tree[rt].sum = (tree[rt].sum + (tree[rt].r - tree[rt].l + 1) * val)%p; tree[rt].minn += val; tree[rt].maxn += val; tree[rt].add = (tree[rt].add + val)%p;//延时标记 return; } pushdown(rt); ll mid = (tree[rt].l + tree[rt].r) >> 1; if (l <= mid) updata_plus(l, r, rt << 1, val); if (r > mid) updata_plus(l, r, rt << 1 | 1, val); pushup(rt); } void updata_ji(ll l, ll r, ll rt, ll val) { if (l <= tree[rt].l && r >= tree[rt].r) { tree[rt].sum = (tree[rt].sum*val)%p; tree[rt].minn *= val; tree[rt].maxn *= val; tree[rt].add = (tree[rt].add * val)%p;//延时标记 tree[rt].mul = (tree[rt].mul * val)%p; return; } pushdown(rt); ll mid = (tree[rt].l + tree[rt].r) >> 1; if (l <= mid) updata_ji(l, r, rt << 1, val); if (r > mid) updata_ji(l, r, rt << 1 | 1, val); pushup(rt); } ll querySum(ll l, ll r, ll rt) { if (l <= tree[rt].l && r >= tree[rt].r) { return tree[rt].sum; } pushdown(rt); ll mid = (tree[rt].l + tree[rt].r) >> 1; ll ans = 0; ll Max = 0; ll Min = inf; if (l <= mid) { ans = querySum(l, r, rt << 1); } if (r > mid) { ans += querySum(l, r, rt << 1 | 1); } return ans%p; } ll queryJi(ll l, ll r, ll rt) { if (l <= tree[rt].l && r >= tree[rt].r) { return tree[rt].ji; } pushdown(rt); ll mid = (tree[rt].l + tree[rt].r) >> 1; ll ans = 1; ll Max = 0; ll Min = inf; if (l <= mid) { ans = queryJi(l, r, rt << 1); } if (r > mid) { ans *= queryJi(l, r, rt << 1 | 1); } return ans; } ll queryMin(ll l, ll r, ll rt) { if (l <= tree[rt].l && r >= tree[rt].r) { return tree[rt].minn; } pushdown(rt); ll mid = (tree[rt].l + tree[rt].r) >> 1; ll ans = 0; ll Max = 0; ll Min = inf; if (l <= mid) { Min = min(queryMin(l, r, rt << 1), Min); } if (r > mid) { Min = min(queryMin(l, r, rt << 1 | 1), Min); } return Min; } ll queryMax(ll l, ll r, ll rt) { if (l <= tree[rt].l && r >= tree[rt].r) { return tree[rt].maxn; } pushdown(rt); ll mid = (tree[rt].l + tree[rt].r) >> 1; ll ans = 0; ll Max = 0; ll Min = inf; if (l <= mid) { Max = max(queryMax(l, r, rt << 1), Max); } if (r > mid) { Max = max(queryMax(l, r, rt << 1 | 1), Max); } return Max; } int main() { ll i, j, k; ll n, m; ll x, y; cin >> n >> m >> p; build(1, n, 1); while (m--) { ll g; cin >> g; if (g == 1) { cin >> x >> y >> k; updata_ji(x, y, 1,k); } if(g==2) { cin >> x >> y >> k; updata_plus(x, y, 1, k); } if (g == 3) { cin >> x >> y; cout << querySum(x, y, 1) % p << endl; } } }