维护序列

解题思路
线段树模板题
code
#include<iostream>
#include<cstdio>
#define int long long
using namespace std;
int n,m,mod;
struct abc{
int s;
int flg1,flg2;
}tree[400010];
void build(int now,int l,int r)
{
tree[now].flg1=1;
if(l==r)
{
scanf("%lld",&tree[now].s);
return;
}
int mid=(l+r)/2;
build(now*2,l,mid);
build(now*2+1,mid+1,r);
tree[now].s=(tree[now*2].s+tree[now*2+1].s)%mod;
}
void down(abc &now,abc &l,abc &r,int x,int y)
{
int mid=(x+y)/2;
l.s=(l.s*now.flg1+(mid-x+1)*now.flg2)%mod;
r.s=(r.s*now.flg1+(y-mid)*now.flg2)%mod;
l.flg1=(l.flg1*now.flg1)%mod;
l.flg2=(l.flg2*now.flg1+now.flg2)%mod;
r.flg1=(r.flg1*now.flg1)%mod;
r.flg2=(r.flg2*now.flg1+now.flg2)%mod;
now.flg1=1;
now.flg2=0;
}
void change1(int now,int l,int r,int x,int y,int w)
{
if(x<=l&&r<=y)
{
tree[now].s=(tree[now].s*w)%mod;
tree[now].flg1=(tree[now].flg1*w)%mod;
tree[now].flg2=(tree[now].flg2*w)%mod;
return;
}
int mid=(l+r)/2;
down(tree[now],tree[now*2],tree[now*2+1],l,r);
if(x<=mid)
change1(now*2,l,mid,x,y,w);
if(y>mid)
change1(now*2+1,mid+1,r,x,y,w);
tree[now].s=(tree[now*2].s+tree[now*2+1].s)%mod;
}
void change2(int now,int l,int r,int x,int y,int w)
{
if(x<=l&&r<=y)
{
tree[now].s=(tree[now].s+(r-l+1)*w)%mod;
tree[now].flg2=(tree[now].flg2+w)%mod;
return;
}
int mid=(l+r)/2;
down(tree[now],tree[now*2],tree[now*2+1],l,r);
if(x<=mid)
change2(now*2,l,mid,x,y,w);
if(y>mid)
change2(now*2+1,mid+1,r,x,y,w);
tree[now].s=(tree[now*2].s+tree[now*2+1].s)%mod;
}
int fd(int now,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
return tree[now].s;
int mid=(l+r)/2,ans=0;
down(tree[now],tree[now*2],tree[now*2+1],l,r);
if(x<=mid)
ans=(ans+fd(now*2,l,mid,x,y))%mod;
if(y>mid)
ans=(ans+fd(now*2+1,mid+1,r,x,y))%mod;
return ans;
}
signed main()
{
cin>>n>>mod;
build(1,1,n);
cin>>m;
while(m--)
{
int k,t,g,c;
scanf("%lld%lld%lld",&k,&t,&g);
if(k==1)
{
scanf("%lld",&c);
change1(1,1,n,t,g,c);
}
if(k==2)
{
scanf("%lld",&c);
change2(1,1,n,t,g,c);
}
if(k==3)
cout<<fd(1,1,n,t,g)<<endl;
}
}
7473



被折叠的 条评论
为什么被折叠?



