线段树
#include <bits/stdc++.h> #include <cstring> #include <iostream> #include <algorithm> #define INF 0x3f3f3f3f #define MOD 1000000007 #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!!\n") #define pb push_back #define pai pair<int,int> //using ll = long long; //using ull= unsigned long long; //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pairint; const double EPS=1e-8; const double PI=acos(-1); const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; const int maxn = 1e5+10; ll a[maxn],mod,ans[maxn]; struct node{ int l,r; ll sum,add,mul,lazy; void update(int a,int m,int len){ add = ((ll)(add*m+a))%mod; mul = ((ll)(m*mul))%mod; sum = ((ll)((ll)sum*m+(ll)len*a))%mod; } }tree[maxn<<2]; void pushup(int rt){ tree[rt].sum = (tree[rt<<1].sum + tree[rt<<1|1].sum) % mod; } void pushdown(int rt,int len){ if(tree[rt].add!=0 || tree[rt].mul!=1){ tree[rt<<1].update(tree[rt].add,tree[rt].mul,len-(len>>1)); tree[rt<<1|1].update(tree[rt].add,tree[rt].mul,len>>1); tree[rt].add = 0; tree[rt].mul = 1; } } void build(int rt,int l,int r){ tree[rt].l = l, tree[rt].r = r; tree[rt].add = 0, tree[rt].mul = 1; if(l == r) { tree[rt].sum = a[l]; return ; } int mid = (l+r)/2; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); pushup(rt); } void update(int rt,int l,int r,int add,int mul){ int L = tree[rt].l, R = tree[rt].r; if(l<=L && R<=r){ tree[rt].update(add,mul,R-L+1); return ; } pushdown(rt,R-L+1); int mid = (L+R)/2; if(l<=mid) update(rt<<1,l,r,add,mul); if(r>mid) update(rt<<1|1,l,r,add,mul); pushup(rt); } ll query(int rt,int l,int r){ int L = tree[rt].l, R = tree[rt].r; if(l<=L && R<=r) return tree[rt].sum; else{ ll ans = 0; pushdown(rt,R-L+1); int mid = (L+R)/2; if(l<=mid) ans+=query(rt<<1,l,r)%mod; if(r>mid) ans+=query(rt<<1|1,l,r)%mod; pushup(rt); return ans; } } int main(){ //freopen("input.txt","r",stdin); int n; cin >> n; cin >> mod; for(int i=1; i<=n; i++){ cin >>a[i]; } build(1,1,n); int m; cin >> m; while(m--){ int op; cin >> op; if(op == 1){ //a到b之间乘x int a,b,x; cin >> a >>b >> x; update(1,a,b,0,x); }else if(op == 2){ //a到b之间加x int a,b,add; cin >> a >>b >> add; update(1,a,b,add,1); }else{ int a,b; cin >> a >>b; printf("%lld\n",query(1,a,b)%mod); } } return 0; }