1.区间修改
2.区间求gcd
有gcd(x,y,z)=gcd(x,x-y,z-y)
我们可以维护差分序列
维护量有 和sum,最大公约数g,
1.区间修改转换为单点修改
ans=gcd((1,l)sum,(l+1,r)g)
// Problem: interval GCD
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/1033/B
// Memory Limit: 131072 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
using namespace std;
typedef long long ll;
const int N=5e5+9;
ll a[N];
struct node{
int l,r;
ll g,sum;
}seg[N<<2];
ll tl(ll x){return x<<1;}
ll tr(ll x){return x<<1|1;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void pushup(node &id,node &l,node &r){
id.sum=l.sum+r.sum;
id.g=gcd(l.g,r.g);
}
void pushup(int id){
pushup(seg[id],seg[tl(id)],seg[tr(id)]);
}
void build(int id,int l,int r){
seg[id]={l,r};
if(l==r){
ll t=a[l]-a[l-1];
seg[id].g=t;
seg[id].sum=t;
return;
}
int mid=(l+r)>>1;
build(tl(id),l,mid);
build(tr(id),mid+1,r);
pushup(id);
}
void update(int id,int l,int r,int pos,ll v){
if(l==r){
seg[id].g+=v;
seg[id].sum+=v;
return;
}
int mid=(l+r)>>1;
if(mid>=pos){
update(tl(id),l,mid,pos,v);
}else{
update(tr(id),mid+1,r,pos,v);
}
pushup(id);
}
node query(int id,int l,int r){
if(seg[id].l>=l && seg[id].r<=r){
return seg[id];
}else{
int mid=(seg[id].l+seg[id].r)>>1;
if(mid>=r){
return query(tl(id),l,r);
}else if(mid<l){
return query(tr(id),l,r);
}else{
node res;
node left=query(tl(id),l,r);
node right=query(tr(id),l,r);
pushup(res,left,right);
return res;
}
}
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
for(int i=1;i<=m;i++){
char op;
cin>>op;
if(op=='C'){
int l,r;
ll d;
cin>>l>>r>>d;
update(1,1,n,l,d);
if(r+1>n){
continue;
}
update(1,1,n,r+1,-d);
}else{
int l,r;
cin>>l>>r;
cout<<abs(gcd(query(1,1,l).sum,query(1,l+1,r).g))<<'\n';
}
}
return 0;
}