An easy problem C
Time Limit: 4000/2000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
N个数排成一列,有三种操作。1.给一段区间内的每个数乘上一个非负整数。2.给一段区间内的每个数加上一个非负整数.3.询问一段区间的和模上P的值。
Input
第一行两个整数N(1≤N≤100000)表示数的个数,P(1≤P≤1000000000)表示模的值。接下来一行N个整数ai(0≤ai≤1000000000),接下来一行一个整数M(1≤M≤100000)表示操作数量,接下来M行每行描述一个操作。第一种操作描述:1 L R C(0≤C≤1000000000),表示把L到R这段区间每个数乘上一个C。第二种操作描述:2 L R C(0≤C≤1000000000),表示把L到R这段区间每个数加上一个C。第三种操作3 L R 表示询问L到R这段区间内的数的和模上P的值。
Output
对面每个询问,输出对应的答案,每个询问占一行。
Sample input and output
Sample Input | Sample Output |
---|---|
7 43 1 2 3 4 5 6 7 5 1 2 5 5 3 2 4 2 3 7 9 3 1 3 3 4 7 | 2 35 8 |
分清乘与加的先后关系,这题就简单多了;
对于一个区间,如果要乘,不止要原本的乘val,还要把要加的数也乘上val
如果要加,那就无所谓了
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N=100005;
typedef long long ll;
ll t[N<<2],ladd[N<<2],lmul[N<<2],n,p,m;
void build(ll l,ll r,ll rt)
{
lmul[rt]=1,ladd[rt]=0;
if(l==r)
{
scanf("%lld",&t[rt]);
return;
}
ll m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
t[rt]=(t[rt<<1]+t[rt<<1|1])%p;
}
void pushdown(ll rt,ll num)
{
ladd[rt<<1]=(ladd[rt<<1]*lmul[rt]+ladd[rt])%p;
ladd[rt<<1|1]=(ladd[rt<<1|1]*lmul[rt]+ladd[rt])%p;
lmul[rt<<1]=(lmul[rt<<1]*lmul[rt])%p;
lmul[rt<<1|1]=(lmul[rt<<1|1]*lmul[rt])%p;
t[rt<<1]=(t[rt<<1]*lmul[rt]+(num-num/2)*ladd[rt])%p;
t[rt<<1|1]=(t[rt<<1|1]*lmul[rt]+(num/2)*ladd[rt])%p;
ladd[rt]=0;
lmul[rt]=1;
}
void updata(ll x,ll y,ll l,ll r,ll rt,ll val,ll op)
{
if(x<=l&&r<=y)
{
if(op==1)
{
ladd[rt]=(ladd[rt]*val)%p;
lmul[rt]=(lmul[rt]*val)%p;
t[rt]=(t[rt]*val)%p;
}
else
{
ladd[rt]=(ladd[rt]+val);
t[rt]=(t[rt]+(r-l+1)*val)%p;
}
return;
}
pushdown(rt,r-l+1);
ll m=(l+r)>>1;
if(x<=m)
updata(x,y,l,m,rt<<1,val,op);
if(y>m)
updata(x,y,m+1,r,rt<<1|1,val,op);
t[rt]=(t[rt<<1]+t[rt<<1|1])%p;
}
ll query(ll x,ll y,ll l,ll r,ll rt)
{
if(x<=l&&y>=r)
return t[rt]%p;
pushdown(rt,r-l+1);
ll m=(l+r)>>1;
ll res=0;
if(x<=m)
res+=query(x,y,l,m,rt<<1);
if(y>m)
res+=query(x,y,m+1,r,rt<<1|1);
return res%p;
}
int main()
{
scanf("%lld%lld",&n,&p);
build(1,n,1);
scanf("%lld",&m);
ll x,y,val,op;
for(ll i=0;i<m;i++)
{
scanf("%lld",&op);
if(op==1)
{
scanf("%lld%lld%lld",&x,&y,&val);
updata(x,y,1,n,1,val,1);
}
else if(op==2)
{
scanf("%lld%lld%lld",&x,&y,&val);
updata(x,y,1,n,1,val,2);
}
else
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(x,y,1,n,1));
}
}
}