题目链接:The Child and Sequence
题目要求的操作:
1 区间求和
2 区间取模
3 单点修改
#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
long long a[maxn],s[maxn*4],n,m,mx[4*maxn];
void build(int l,int r,int o)
{
s[o]=0;//区间和
mx[o]=0;//区间最大值
if(l==r)
{
s[o]=a[l];
mx[o]=a[l];
return ;
}
int mid=(l+r)/2;
build(l,mid,o*2);
build(mid+1,r,o*2+1);
s[o]=s[o*2+1]+s[o*2];
mx[o]=max(mx[o*2+1],mx[o*2]);
}
void update2(int l,int r,int o,int x,int y,int p)
{
if(p>mx[o])//a%b,如果 b>a,a%b=a
return ;
if(l==r)//暴力找到根节点
{
s[o]=s[o]%p;
mx[o]=s[o];
return ;
}
int mid=(l+r)/2;
if(x<=mid)
update2(l,mid,o*2,x,y,p);
if(y>mid)
update2(mid+1,r,o*2+1,x,y,p);
s[o]=s[o*2+1]+s[o*2];
mx[o]=max(mx[o*2+1],mx[o*2]);
}
void update3(int l,int r,int o,int x,int p)
{
if(l==r)
{
s[o]=p;
mx[o]=p;
return ;
}
int mid=(l+r)/2;
if(x<=mid)
update3(l,mid,o*2,x,p);
else
update3(mid+1,r,o*2+1,x,p);
s[o]=s[o*2]+s[o*2+1];
mx[o]=max(mx[o*2+1],mx[o*2]);
}
long long query(int l,int r,int x,int y,int o)
{
if(x<=l&&y>=r)
return s[o];
int mid=(l+r)/2;
long long sum=0;
if(x<=mid)
sum+=query(l,mid,x,y,o*2);
if(y>mid)
sum+=query(mid+1,r,x,y,o*2+1);
return sum;
}
int main()
{
scanf("%d%d",&n,&m);
int i;
for(i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,n,1);
while(m--)
{
//printf("^^^\n");
int k;
int x,y,z;
scanf("%d",&k);
if(k==1)
{
scanf("%d%d",&x,&y);
printf("%lld\n",query(1,n,x,y,1));
}
else if(k==2)
{
scanf("%d%d%d",&x,&y,&z);
update2(1,n,1,x,y,z);
}
else
{
scanf("%d%d",&x,&y);
update3(1,n,1,x,y);
}
}
}