题目大意:给定一个有 个元素序列,有四种操作和一种询问.
- 1 L R K 让区间
的元素加上
.
- 2 L R K 让区间
的元素乘上
.
- 3 L R K 让区间
的元素变为
.
- 4 L R K 在末尾位置添加一个元素值为
.
- 5 L R 询问区间
元素的值的和.
分析: 赛中分析,前四个操作都是线段树的操作,后面看到操作四,以为不能写线段树,直接码分块,后面T了三十发直接自闭.
赛后分析:显然我们可以直接建n+m大小的线段树,然后直接操作.(惊了
推标记直接用两个mul 和add 维护乘法和加法,这种操作就是码板子.
#include<bits/stdc++.h>
#define ls cur<<1
#define rs cur<<1|1
using namespace std;
const int maxn=2e5+10;
typedef long long ll;
ll mod;
struct node1{
int l;
int r;
ll sum1,mul,lazy;
}t[maxn<<2];
ll a[maxn];
void pushup( int cur ) //ok
{
t[cur].sum1=( t[ls].sum1+t[rs].sum1 )%mod;
}
void cal( int cur,ll x,ll y )
{
ll len=1ll*( t[cur].r-t[cur].l+1 );
t[cur].sum1=( x*t[cur].sum1%mod+(y*len)%mod )%mod;
t[cur].mul=(t[cur].mul*x)%mod;
t[cur].lazy=( t[cur].lazy*x%mod+y )%mod;
}
void pushdown( int cur ) //ok
{
if( t[cur].mul!=1ll || t[cur].lazy )
{
cal( ls,t[cur].mul,t[cur].lazy );
cal( rs,t[cur].mul,t[cur].lazy );
t[cur].mul=1ll;
t[cur].lazy=0;
}
}
void build( int cur ,int l,int r )
{
t[cur].l=l;t[cur].r=r;
t[cur].mul=1ll;
t[cur].lazy=t[cur].sum1=0ll;
if( l == r )
{
t[cur].sum1=a[l];
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushup( cur );
}
void update( int cur,int L,int R ,ll x,ll y )
{
int l=t[cur].l,r=t[cur].r;
if( L<=l && r<=R )
{
cal(cur,x,y);
return;
}
pushdown( cur );
int mid=(l+r)>>1;
if( L<=mid ) update(ls,L,R,x,y);
if( R>mid ) update(rs,L,R,x,y);
pushup( cur );
}
ll get_Sum( int cur,int L,int R )
{
int l=t[cur].l,r=t[cur].r;
if( L<=l && r<=R ) return t[cur].sum1;
ll ans=0;
pushdown( cur );
int mid=(l+r)>>1;
if( L<=mid ) ans+=get_Sum(ls,L,R);
ans%=mod;
if( R>mid ) ans+=get_Sum(rs,L,R);
ans%=mod;
return ans;
}
int main()
{
int n,m;
scanf("%d%d%lld",&n,&m,&mod);
for( int i=1;i<=n;i++ ) scanf("%lld",&a[i]);
build(1,1,n+m);
int now=n;
while( m-- )
{
int op,l,r,c;
scanf("%d",&op);
if( op <=3 )
{
scanf("%d%d%d",&l,&r,&c);
if( op==1 ) update(1,l,r,1,c);
if( op==2 ) update(1,l,r,c,0);
if( op==3 ) update(1,l,r,0,c);
}
else if( op==4 )
{
scanf("%d",&c);
now++;
update(1,now,now,0,c);
}
else
{
scanf("%d%d",&l,&r);
printf("%lld\n",get_Sum(1,l,r));
}
}
}
京公网安备 11010502036488号