- 问题转化成,求解线段树上单点修改维护差分后区间gcd,而每段长度的开头需要通过维护原数组的差分数组维护单点,满足树状数组
- 最大公约数的性质:满足辗转相除法的性质推广多元
- 线段树和树状数组基操
-
具体实现 
-
实现
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<iomanip>
using namespace std;
const int maxn=200005;
#define int long long
inline int read()
{
int x=0,y=1; char c=getchar();
while(c<'0'||c>'9') {if(c=='-') y=-1; c=getchar();}
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x*y;
}
int n,a[maxn];
int m;
int gcd(int a,int b)
{
if(!b) return a;
return gcd(b,a%b);
}
struct BITtree
{
int c[maxn];
int lowbit(int x) {return x&(-x);}
void add(int now,int x)
{
for(;now<=n;now+=lowbit(now)) c[now]+=x;
return ;
}
int query(int now)
{
int sum=0;
for(;now;now-=lowbit(now)) sum+=c[now];
return sum;
}
}bit;
int tree[maxn*4];
void pushup(int id)
{
tree[id]=gcd(tree[id<<1],tree[id<<1|1]);
return ;
}
void build(int id,int l,int r)
{
if(l==r)
{
tree[id]=a[l]-a[l-1];
return ;
}
int mid=(l+r)>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
pushup(id);
return ;
}
void modify(int id,int l,int r,int pos,int val)
{
if(l==r&&r==pos)
{
tree[id]+=val;
return ;
}
int mid=(l+r)>>1;
if(pos<=mid) modify(id<<1,l,mid,pos,val);
else modify(id<<1|1,mid+1,r,pos,val);
pushup(id);
return ;
}
int query(int id,int l,int r,int x,int y)
{
if(x<=l&&r<=y) return tree[id];
int ans=0;
int mid=(l+r)>>1;
if(mid>=x) ans=query(id<<1,l,mid,x,y);
if(mid<y) ans=gcd(ans,query(id<<1|1,mid+1,r,x,y));
return ans;
}
signed main()
{
n=read();
for(int i=1;i<=n;i++) a[i]=read();
build(1,1,n);
m=read();
while(m--)
{
int type,l,r,x;
type=read();
if(type)
{
l=read(); r=read();
int new_l=a[l]+bit.query(l);
int ans=gcd(new_l,query(1,1,n,l+1,r));
printf("%lld\n",(ans<0)?-ans:ans);
}
else
{
l=read(); r=read();
x=read();
bit.add(l,x);
modify(1,1,n,l,x);
if(r>=n) continue;
bit.add(r+1,-x);
modify(1,1,n,r+1,-x);
}
}
return 0;
}
/*5
2 6 4 1 5
3
1 2 3
0 3 4 5
1 3 4
*/
- 考虑gcd的动态求解应该优先考虑辗转相除应用的性质,将区间修改改为单点修改
- 学会封装结构体的数据结构
- 差分数组的l位+x,r+1位-x,也就是说从l到r的区间中真正改动的是首位的值,而-x则会成为以r+1为首位的序列该变量,因此考虑维护一端值即可
- 需要继续加强码力
太蒟