震惊,双倍经验,依旧是线段树的乘法修改
#includeusing namespace std;const int maxn=1000010;struct sege_tree{ int l; int r; long long lazymul; long long lazyadd; long long v;}tree[7*maxn];int a[maxn];long long p,ans;int n,m,opt,l,r;long long t;void build(int now,int l,int r){ tree[now].l=l; tree[now].r=r; tree[now].lazymul=1; tree[now].lazyadd=0; if(l==r) { tree[now].v=a[l]; return; } else { int mid=(l+r)>>1; build(now*2,l,mid); build(now*2+1,mid+1,r); tree[now].v=tree[now*2].v+tree[now*2+1].v; } tree[now].v%=p; return;}void pushdown(int now,int l,int r)//标记下传 { int mid=(l+r)>>1; tree[now*2].v=(tree[now*2].v*tree[now].lazymul+tree[now].lazyadd*(mid-l+1))%p; tree[now*2+1].v=(tree[now*2+1].v*tree[now].lazymul+tree[now].lazyadd*(r-mid))%p; tree[now*2].lazymul=(tree[now*2].lazymul*tree[now].lazymul)%p; tree[now*2+1].lazymul=(tree[now*2+1].lazymul*tree[now].lazymul)%p; tree[now*2].lazyadd=(tree[now*2].lazyadd*tree[now].lazymul+tree[now].lazyadd)%p; tree[now*2+1].lazyadd=(tree[now*2+1].lazyadd*tree[now].lazymul+tree[now].lazyadd)%p; tree[now].lazymul=1; tree[now].lazyadd=0; return;}void update1(int now,int stdl,int stdr,int l,int r,long long k){ if(l>stdr||r =stdr) { tree[now].v=(tree[now].v*k)%p; tree[now].lazymul=(tree[now].lazymul*k)%p; tree[now].lazyadd=(tree[now].lazyadd*k)%p; return; } pushdown(now,stdl,stdr); int mid=(stdl+stdr)>>1; update1(now*2,stdl,mid,l,r,k); update1(now*2+1,mid+1,stdr,l,r,k); tree[now].v=(tree[now*2].v+tree[now*2+1].v)%p; return;}void update2(int now,int stdl,int stdr,int l,int r,long long k){ if(l>stdr||r =stdr) { tree[now].lazyadd=(tree[now].lazyadd+k)%p; tree[now].v=(tree[now].v+k*(stdr-stdl+1))%p; return; } pushdown(now,stdl,stdr); int mid=(stdl+stdr)>>1; update2(now*2,stdl,mid,l,r,k); update2(now*2+1,mid+1,stdr,l,r,k); tree[now].v=(tree[now*2].v+tree[now*2+1].v)%p;}long long query(int now,int stdl,int stdr,int l,int r){ if(stdl>r||stdr =l&&stdr<=r) { return tree[now].v; } pushdown(now,stdl,stdr); int mid=(stdl+stdr)>>1; return (query(now*2,stdl,mid,l,r)+query(now*2+1,mid+1,stdr,l,r))%p;}int main(){ cin>>n>>p; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } build(1,1,n); cin>>m; while(m--) { scanf("%d",&opt); if(opt==1) { cin>>l>>r>>t; update1(1,1,n,l,r,t); } else if(opt==2) { cin>>l>>r>>t; update2(1,1,n,l,r,t); } else { cin>>l>>r; cout< <