有路过的帮个忙。谢谢!
#include <bits/stdc++.h>
#include <cstring>
#define INF 0x7f7f7f7f
#define eps 1e-6
#define ll long long
#define ull unsigned long long
#define N 400010
using namespace std;
ll n,m,p;
struct Node{
ll tag1,tag2,num;
}tree[N];
ll a[N];
inline ll read(){
ll s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
#define mod(n) (n)%=p//(n)=(n)
#define ls u*2
#define rs u*2+1
#define mid (l+r)/2
inline void print_tree()
{
puts("tree:");
ll tot=0,c=0;
for(ll i=1;i<n*2;i++)
{
printf("%d ",tree[i].num);
tot++;
if(tot>=pow(2,c))
{
tot=0;
c++;
printf("\n");
}
}
printf("\n");
}
inline void print_tag1()
{
puts("tag1:");
ll tot=0,c=0;
for(ll i=1;i<n*2;i++)
{
printf("%d ",tree[i].tag1);
tot++;
if(tot>=pow(2,c))
{
tot=0;
c++;
printf("\n");
}
}
printf("\n");
}
inline void print_tag2()
{
puts("tag2:");
ll tot=0,c=0;
for(ll i=1;i<n*2;i++)
{
printf("%d ",tree[i].tag2);
tot++;
if(tot>=pow(2,c))
{
tot=0;
c++;
printf("\n");
}
}
printf("\n");
}
inline void debug()
{
print_tree();
print_tag1();
print_tag2();
}
inline void build(ll u,ll l,ll r)
{
tree[u].tag1 = 0;
tree[u].tag2 = 1;
if(l == r)
{
tree[u].num = a[l]; mod(tree[u].num);
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
tree[u].num = (tree[ls].num + tree[rs].num);
mod(tree[u].num);
}
inline void pushdown(ll u,ll l,ll r)
{
//num
tree[ls].num = tree[ls].num * tree[u].tag2 + tree[u].tag1 * (mid-l+1); mod(tree[ls].num);
tree[rs].num = tree[rs].num * tree[u].tag2 + tree[u].tag1 * (r-mid); mod(tree[rs].num);
//tag1
tree[ls].tag1 = tree[ls].tag1 * tree[u].tag2 + tree[u].tag1; mod(tree[ls].tag1);
tree[rs].tag1 = tree[rs].tag1 * tree[u].tag2 + tree[u].tag1; mod(tree[ls].tag1);
//tag2
tree[ls].tag2 = tree[ls].tag2 * tree[u].tag2; mod(tree[ls].tag2);
tree[rs].tag2 = tree[rs].tag2 * tree[u].tag2; mod(tree[rs].tag1);
//复原
tree[u].tag1 = 0;
tree[u].tag2 = 1;
//debug
// printf("pushdown:");
// debug();
}
inline void up_add(ll u,ll l,ll r,ll L,ll R,ll k)
{
// printf("add: u=%d, l=%d, r=%d, L=%d, R=%d, k=%d\n", u, l, r, L, R, k);
if(r < L || l > R) return;
if(L <= l && R >= r)
{
tree[u].tag1 = tree[u].tag1 + k; mod(tree[u].tag1);
tree[u].num = tree[u].num + k * ( r - l + 1); mod(tree[u].num);
return;
}
pushdown(u,l,r);
up_add(ls,l,mid,L,R,k);
up_add(rs,mid+1,r,L,R,k);
tree[u].num = tree[ls].num + tree[rs].num; mod(tree[u].num);
}
inline void up_mul(ll u,ll l,ll r,ll L,ll R,ll k)
{
// printf("mul: u=%d, l=%d, r=%d, L=%d, R=%d, k=%d\n", u, l, r, L, R, k);
if(r < L || l > R) return;
if(L <= l && R >= r)
{
tree[u].tag2 *= k; mod(tree[u].tag2);
tree[u].tag1 = tree[u].tag1 * k; mod(tree[u].tag1);
tree[u].num = tree[u].num * k; mod(tree[u].num);
return;
}
pushdown(u,l,r);
up_mul(ls,l,mid,L,R,k);
up_mul(rs,mid+1,r,L,R,k);
tree[u].num = tree[ls].num + tree[rs].num; mod(tree[u].num);
}
inline ll query(ll u,ll l,ll r,ll L,ll R)
{
// printf("query: u=%d, l=%d, r=%d, L=%d, R=%d\n", u, l, r, L, R);
if(r < L || l > R)
{
// puts("stop");
return 0;
}
if(L <= l && R >= r)
{
// puts("return");
return tree[u].num;
}
pushdown(u,l,r);
// puts("continue");
// printf("pushdown:");
// print_tree();
return (query(ls,l,mid,L,R) + query(rs,mid+1,r,L,R)) % p;
}
inline void init()
{
n = read(),m = read(),p = read();
for(ll i=1;i<=n;i++) a[i] = read();
// puts("build:");
build(1, 1, n);
// debug();
}
int main()
{
// freopen("in1.txt","r",stdin);
init();
for(ll i=1;i<=m;i++)
{
// printf("m=%d,i=%d\n",m,i);
ll ms=read(),x=read(),y=read(),k;
switch(ms)
{
case 1:
k=read();
up_mul(1,1,n,x,y,k);
break;
case 2:
k=read();
up_add(1,1,n,x,y,k);
break;
case 3:
printf("%lld\n",query(1,1,n,x,y));
break;
}
// print_tree();
}
return 0;
}