线段树维护差分数组,求gcd
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+100;
int sum[maxn*4];
int gcd[maxn*4],maxx[maxn*4];
int a[maxn];
void pushup(int i)
{
sum[i]=sum[i*2]+sum[i*2+1];
gcd[i]=__gcd(gcd[i*2],gcd[i*2+1]);
maxx[i]=max(maxx[i*2],maxx[i*2+1]);
}
void build(int i,int l,int r)
{
if(l==r)
{
int x;
if(l==1)
{
sum[i]=gcd[i]=maxx[i]=a[l];
}
else
{
sum[i]=a[l]-a[l-1];
gcd[i]=maxx[i]=abs(sum[i]);
}
return;
}
int mid=l+r>>1;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
pushup(i);
}
void update(int i,int l,int r,int x,int t)
{
if(l==r)
{
sum[i]+=t;
gcd[i]=maxx[i]=abs(sum[i]);
return ;
}
int mid=l+r>>1;
if(x<=mid)
update(i*2,l,mid,x,t);
else
update(i*2+1,mid+1,r,x,t);
pushup(i);
}
int query_max(int i,int l,int r,int x,int y)
{
if(x<=l&&y>=r)
{
return maxx[i];
}
int mid=l+r>>1;
int ans=0;
if(x<=mid)
ans=max(ans,query_max(i*2,l,mid,x,y));
if(y>mid)
ans=max(ans,query_max(i*2+1,mid+1,r,x,y));
return ans;
}
int query_sum(int i,int l,int r,int x,int y)
{
if(x<=l&&y>=r)
{
return sum[i];
}
int mid=l+r>>1;
int ans=0;
if(x<=mid)
ans+=query_sum(i*2,l,mid,x,y);
if(y>mid)
ans+=query_sum(i*2+1,mid+1,r,x,y);
return ans;
}
int query_gcd(int i,int l,int r,int x,int y)
{
if(x<=l&&y>=r)
{
return gcd[i];
}
int mid=l+r>>1;
int ans=0;
if(x<=mid)
ans=__gcd(ans,query_gcd(i*2,l,mid,x,y));
if(y>mid)
ans=__gcd(ans,query_gcd(i*2+1,mid+1,r,x,y));
return ans;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,1,n);
int op,x,y,t;
while(m--)
{
scanf("%d%d%d",&op,&x,&y);
if(op==1)
{
scanf("%d",&t);
update(1,1,n,x,t);
update(1,1,n,y+1,-t);
}
else if(op==2)
{
printf("%d\n",query_max(1,1,n,x+1,y));
}
else
{
if(x==y)
{
printf("%d\n",query_sum(1,1,n,1,x));
}
else
{
printf("%d\n",__gcd(query_sum(1,1,n,1,x),query_gcd(1,1,n,x+1,y)));
}
}
}
return 0;
}