rt,代码应该还是比较好懂的。若又看不懂的地方可在评论区询问。将使用大号 roumeideclown 关注。
这对我来说真的很重要,这道题已经调了 2 months 了,求求了 thx
#include<bits/stdc++.h>
#define mod m
using namespace std;
typedef long long ll;
const int N=1e5+5;
ll n,q,m,a[N];
struct node {
ll l,r,sum,mul,add;
} tree[N*4];
ll ls(ll p) {
return p<<1;
}
ll rs(ll p) {
return p<<1|1;
}
void pushup(ll p) {
tree[p].sum=(tree[ls(p)].sum+tree[rs(p)].sum)%mod;
}
void build(ll p,ll l,ll r) {
tree[p].l=l,tree[p].r=r;
tree[p].sum=tree[p].add=0;
tree[p].mul=1;
if(l==r) {
tree[p].sum=a[l]%mod;
return;
}
ll mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
pushup(p);
}
void pushdown(ll p) {
tree[ls(p)].sum=(tree[ls(p)].sum*tree[p].mul%mod+tree[p].add*(tree[ls(p)].r-tree[ls(p)].l+1)%mod)%mod;
tree[rs(p)].sum=(tree[rs(p)].sum*tree[p].mul%mod+tree[p].add*(tree[rs(p)].r-tree[rs(p)].l+1)%mod)%mod;
tree[ls(p)].add=(tree[ls(p)].add*tree[p].mul%mod+tree[p].add)%mod;
tree[rs(p)].add=(tree[rs(p)].add*tree[p].mul%mod+tree[p].add)%mod;
(tree[ls(p)].mul*=tree[p].mul)%=mod;
(tree[rs(p)].mul*=tree[p].mul)%=mod;
tree[p].mul=1,tree[p].add=0;
}
void upd1(ll p,ll l,ll r,ll k) {
if(l<=tree[p].l&&r>=tree[p].r) {
(tree[p].sum*=k)%=mod;
(tree[p].mul*=k)%=mod;
(tree[p].add*=k)%=mod;
return;
}
pushdown(p);
ll mid=(tree[p].l+tree[p].r)>>1;
if(l<=mid) upd1(ls(p),l,r,k);
if(r>mid) upd1(rs(p),l,r,k);
pushup(p);
}
void upd2(ll p,ll l,ll r,ll k) {
if(l<=tree[p].l&&r>=tree[p].r) {
(tree[p].sum+=k*(tree[p].r-tree[p].l+1)%mod)%=mod;
(tree[p].add+=k)%=mod;
return;
}
pushdown(p);
ll mid=(tree[p].l+tree[p].r)>>1;
if(l<=mid) upd2(ls(p),l,r,k);
if(r>mid) upd2(rs(p),l,r,k);
return;
}
ll query(ll p,ll l,ll r) {
if(l<=tree[p].l&&r>=tree[p].r) return tree[p].sum;
pushdown(p);
ll mid=(tree[p].l+tree[p].r)>>1,res=0;
if(l<=mid) (res+=query(ls(p),l,mid))%=mod;
if(r>mid) (res+=query(rs(p),mid+1,r))%=mod;
return res;
}
int main() {
// ios::sync_with_stdio(false);
// cin.tie(0),cout.tie(0);
scanf("%lld%lld%lld",&n,&q,&m);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,1,n);
while(q--) {
ll op,x,y,k;
scanf("%lld%lld%lld",&op,&x,&y);
if(op==1) {
scanf("%lld",&k);
upd1(1,x,y,k);
}
else if(op==2) {
scanf("%lld",&k);
upd2(1,x,y,k);
}
else printf("%lld\n",query(1,x,y));
}
return 0;
}