1.區間修改(加&&乘),區間查詢
https://www.luogu.org/problemnew/show/P3373
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
struct Node
{
long long l,r,mlz,plz,sum;
}tree[400010];
ll putnum[100010];
ll n,m,p;
void build(ll i,ll l,ll r)
{
tree[i].l=l;tree[i].r=r;
tree[i].plz=0;tree[i].mlz=1;
if(l==r)
{
tree[i].sum=putnum[l]%p;
return;
}
ll mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
tree[i].sum=(tree[i<<1].sum+tree[i<<1|1].sum)%p;
}
void init()
{
scanf("%lld%lld%lld",&n,&m,&p);
for(ll i=1;i<=n;i++) scanf("%lld",&putnum[i]);
build(1,1,n);
}
void push_down(ll i)
{
long long k1=tree[i].mlz,k2=tree[i].plz;
tree[i<<1].sum=(tree[i<<1].sum*k1+k2*(tree[i<<1].r-tree[i<<1].l+1))%p;
tree[i<<1|1].sum=(tree[i<<1|1].sum*k1+k2*(tree[i<<1|1].r-tree[i<<1|1].l+1))%p;
tree[i<<1].mlz=(tree[i<<1].mlz*k1)%p;
tree[i<<1|1].mlz=(tree[i<<1|1].mlz*k1)%p;
tree[i<<1].plz=(tree[i<<1].plz*k1+k2)%p;
tree[i<<1|1].plz=(tree[i<<1|1].plz*k1+k2)%p;
tree[i].plz=0;
tree[i].mlz=1;
return ;
}
void mul(ll i,ll l,ll r,ll k)
{
if(tree[i].r<=r && tree[i].l>=l)
{
tree[i].sum*=k;
tree[i].sum%=p;
tree[i].mlz*=k;
tree[i].mlz%=p;
tree[i].plz*=k;
tree[i].plz%=p;
return;
}
push_down(i);
if(tree[i<<1].r>=l) mul(i<<1,l,r,k);
if(tree[i<<1|1].l<=r) mul(i<<1|1,l,r,k);
tree[i].sum=(tree[i<<1].sum+tree[i<<1|1].sum)%p;
}
void add(ll i,ll l,ll r,ll k)
{
if(tree[i].r<=r && tree[i].l>=l)
{
tree[i].sum+=k*(tree[i].r-tree[i].l+1);
tree[i].sum%=p;
tree[i].plz+=k;
tree[i].plz%=p;
return;
}
push_down(i);
if(tree[i<<1].r>=l) add(i<<1,l,r,k);
if(tree[i<<1|1].l<=r) add(i<<1|1,l,r,k);
tree[i].sum=(tree[i<<1].sum+tree[i<<1|1].sum)%p;
}
ll Search(ll i,ll l,ll r)
{
if(tree[i].l>=l && tree[i].r<=r)
return (tree[i].sum)%p;
if(tree[i].r<l || tree[i].l>r)
return 0;
push_down(i);
return (Search(i<<1,l,r)+Search(i<<1|1,l,r))%p;
}
int main()
{
init();
ll tag,x,y,k;
for(ll i=1;i<=m;i++)
{
scanf("%lld%lld%lld",&tag,&x,&y);
if(tag==1)
{
scanf("%lld",&k);
mul(1,x,y,k);
}
if(tag==2)
{
scanf("%lld",&k);
add(1,x,y,k);
}
if(tag==3)
{
printf("%lld\n",Search(1,x,y));
}
}
return 0;
}
2.單點修改,區間查詢
https://www.luogu.org/problemnew/show/P3374
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int Maxx=500000;
struct Node
{
int l,r,sum;
}tree[Maxx*4+50];
int putnum[Maxx+10];
int n,m;
void build(int i,int l,int r)
{
tree[i].l=l;
tree[i].r=r;
if(l==r)
{
tree[i].sum=putnum[l];
return;
}
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;
}
void add(int i,int x,int y)
{
if(tree[i].l==tree[i].r)
{
tree[i].sum+=y;
return;
}
if(x<=tree[i<<1].r) add(i<<1,x,y);
else add(i<<1|1,x,y);
tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;
}
int Search(int i,int l,int r)
{
if(tree[i].l>=l && tree[i].r<=r) return tree[i].sum;
if(tree[i].r<l || tree[i].l>r) return 0;
return Search(i<<1,l,r)+Search(i<<1|1,l,r);
}
void init()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
scanf("%d",&putnum[i]);
build(1,1,n);
}
int main()
{
init();
int x,y,tag;
for(int i=1;i<=m;i++)
{
scanf("%d",&tag);
scanf("%d%d",&x,&y);
if(tag==1) add(1,x,y);
if(tag==2) printf("%d\n",Search(1,x,y));
}
return 0;
}
3.區間修改(加),區間查詢
https://www.luogu.org/problemnew/show/P3372
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
struct Node
{
long long l,r,lz,sum;
}tree[400010];
ll putnum[100010];
ll n,m;
void build(ll i,ll l,ll r)
{
tree[i].l=l;tree[i].r=r;
tree[i].lz=0;
if(l==r)
{
tree[i].sum=putnum[l];
return;
}
ll mid=(l+r)>>1;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tree[i].sum=(tree[i*2].sum+tree[i*2+1].sum);
}
void init()
{
scanf("%lld%lld",&n,&m);
for(ll i=1;i<=n;i++) scanf("%lld",&putnum[i]);
build(1,1,n);
}
void push_down(ll i)
{
if(tree[i].lz)
{
tree[i*2].lz+=tree[i].lz;
tree[i*2+1].lz+=tree[i].lz;
ll mid=(tree[i].l+tree[i].r)/2;
tree[i*2].sum+=tree[i].lz*(mid-tree[i*2].l+1);
tree[i*2+1].sum+=tree[i].lz*(tree[i*2+1].r-mid);
tree[i].lz=0;
}
}
void add(ll i,ll l,ll r,ll k)
{
if(tree[i].r<=r && tree[i].l>=l)
{
tree[i].sum+=k*(tree[i].r-tree[i].l+1);
tree[i].lz+=k;
return;
}
push_down(i);
if(tree[i*2].r>=l) add(i*2,l,r,k);
if(tree[i*2+1].l<=r) add(i*2+1,l,r,k);
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
}
ll Search(ll i,ll l,ll r)
{
if(tree[i].l>=l && tree[i].r<=r)
return tree[i].sum;
if(tree[i].r<l || tree[i].l>r)
return 0;
push_down(i);
return Search(i*2,l,r)+Search(i*2+1,l,r);
}
int main()
{
init();
ll tag,x,y,k;
for(ll i=1;i<=m;i++)
{
scanf("%lld%lld%lld",&tag,&x,&y);
if(tag==1)
{
scanf("%lld",&k);
add(1,x,y,k);
}
if(tag==2)
{
printf("%lld\n",Search(1,x,y));
}
}
return 0;
}