线段树 乘+加
居然错在了输入是循环m而不是n,卡了一个小时。。。。。。
一份优美的代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll maxn=1e5+1;
struct T
{
ll data,add,mul,l,r;
}node[4*maxn];
ll n,m,p,a[maxn],i;
ll type,x,y,k;
void build(ll pos,ll l,ll r)
{
node[pos].l=l;
node[pos].r=r;
node[pos].add=0;
node[pos].mul=1;
if(l==r)
{
node[pos].data=a[l]%p;
return;
}
ll mid=(l+r)>>1;
build(pos<<1,l,mid);
build(pos<<1|1,mid+1,r);
node[pos].data=(node[pos<<1].data+node[pos<<1|1].data)%p;
}
void pushdown(ll pos)
{
node[pos<<1].add=(node[pos<<1].add*node[pos].mul%p+node[pos].add)%p;
node[pos<<1|1].add=(node[pos<<1|1].add*node[pos].mul%p+node[pos].add)%p;
node[pos<<1].mul=(node[pos<<1].mul*node[pos].mul)%p;
node[pos<<1|1].mul=(node[pos<<1|1].mul*node[pos].mul)%p;
node[pos<<1].data=(node[pos<<1].data%p*node[pos].mul%p+node[pos].add*(node[pos<<1].r-node[pos<<1].l+1)%p)%p;
node[pos<<1|1].data=(node[pos<<1|1].data%p*node[pos].mul%p+node[pos].add*(node[pos<<1|1].r-node[pos<<1|1].l+1)%p)%p;
node[pos].add=0;
node[pos].mul=1;
return;
}
void changeplus(ll pos,ll l,ll r,ll v)
{
if(l<=node[pos].l&&node[pos].r<=r)
{
node[pos].add=(node[pos].add+v)%p;
node[pos].data=(node[pos].data+v*(node[pos].r-node[pos].l+1)%p)%p;
return;
}
pushdown(pos);
ll mid=(node[pos].l+node[pos].r)>>1;
if(l<=mid) changeplus(pos<<1,l,r,v);
if(r>mid) changeplus(pos<<1|1,l,r,v);
node[pos].data=(node[pos<<1].data+node[pos<<1|1].data)%p;
}
void changemul(ll pos,ll l,ll r,ll v)
{
if(l<=node[pos].l&&node[pos].r<=r)
{
node[pos].mul=node[pos].mul*v%p;
node[pos].add=node[pos].add*v%p;
node[pos].data=node[pos].data*v%p;
return;
}
pushdown(pos);
ll mid=(node[pos].l+node[pos].r)>>1;
if(l<=mid) changemul(pos<<1,l,r,v);
if(r>mid) changemul(pos<<1|1,l,r,v);
node[pos].data=(node[pos<<1].data+node[pos<<1|1].data)%p;
}
ll query(ll pos,ll l,ll r)
{
if(l<=node[pos].l&&node[pos].r<=r)
{
return node[pos].data;
}
pushdown(pos);
ll answer=0,mid=(node[pos].l+node[pos].r)>>1;
if(l<=mid) answer=(answer+query(pos<<1,l,r))%p;
if(r>mid) answer=(answer+query(pos<<1|1,l,r))%p;
return answer%p;
}
int main()
{
scanf("%lld%lld%lld",&n,&m,&p);
for(i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,1,n);
for(i=1;i<=m;i++)
{
scanf("%lld%lld%lld",&type,&x,&y);
if(type==1)
{
scanf("%lld",&k);
changemul(1,x,y,k);
}
if(type==2)
{
scanf("%lld",&k);
changeplus(1,x,y,k);
}
if(type==3)
{
printf("%lld\n",query(1,x,y));
}
}
}