有点考验思维

首 先 区 间 查 询 , 单 点 修 改 , 想 到 线 段 树 可 以 维 护 区 间 g c d 首先区间查询,单点修改,想到线段树可以维护区间gcd ,,线gcd

主 要 是 查 询 区 间 g c d 是 否 是 x 怎 么 办 。 主要是查询区间gcd是否是x怎么办。 gcdx

我 们 只 能 查 询 区 间 的 g c d , 但 是 这 里 可 以 修 改 1 个 数 我们只能查询区间的gcd,但是这里可以修改1个数 gcd,1

若 区 间 g c d 是 x 的 倍 数 , 就 别 去 管 了 \color{Red}若区间gcd是x的倍数,就别去管了 gcdx,

不 用 管 是 否 是 几 倍 , 是 几 倍 都 可 以 改 变 一 个 变 成 x 使 得 g c d = x 不用管是否是几倍,是几倍都可以改变一个变成x使得gcd=x ,x使gcd=x

若 区 间 g c d 不 是 x 的 倍 数 , 一 直 向 下 查 询 直 到 叶 子 节 点 \color{Red}若区间gcd不是x的倍数,一直向下查询直到叶子节点 gcdx,

那 么 这 个 叶 子 节 点 肯 定 要 修 改 , 我 们 把 它 修 改 为 x 那么这个叶子节点肯定要修改,我们把它修改为x ,x

修 改 成 x 的 好 处 是 , 就 算 其 他 区 间 g c d 是 x 的 倍 数 , 最 后 g c d 也 会 变 成 x 修改成x的好处是,就算其他区间gcd是x的倍数,最后gcd也会变成x x,gcdx,gcdx

所以问题转化为查询区间有几个数不是x的倍数

若 都 是 x 的 倍 数 , 显 然 改 变 一 个 数 为 x 就 可 以 满 足 条 件 若都是x的倍数,显然改变一个数为x就可以满足条件 x,x

若 只 有 一 个 数 不 是 x 的 倍 数 , 显 然 改 变 这 个 数 为 x 可 以 满 足 条 件 若只有一个数不是x的倍数,显然改变这个数为x可以满足条件 x,x

否 则 , 必 定 不 满 足 否则,必定不满足 ,

#include <bits/stdc++.h>
using namespace std;
#define lson p<<1,l,mid
#define int long long
#define rson p<<1|1,mid+1,r
const int maxn=2e6+10;
int n,val[maxn],cnt,q;
int gcd(int a,int b){
	return b==0?a:gcd(b,a%b);
}
struct xian{
	int l,r,v;
}a[maxn];
void push_up(int p){
	a[p].v=gcd( a[p<<1].v,a[p<<1|1].v );
}
void build(int p,int l,int r)
{
	a[p] = (xian){l,r,0};
	if( l==r )
	{
		a[p].v=val[l];
		return;
	}
	int mid=l+r>>1;
	build(lson); build(rson);
	push_up(p);
}
void change(int p,int l,int r,int k)
{
	if( a[p].l>=l&&a[p].r<=r )
	{
		a[p].v=k;
		return;
	}
	int mid=a[p].l+a[p].r>>1;
	if( mid>=l )	change(p<<1,l,r,k);
	if( mid<r )	change(p<<1|1,l,r,k);
	push_up(p);
}
void ask(int p,int l,int r,int x)//查询区间l,r 
{
	if( cnt>1 )	return;
	if( a[p].v%x==0 )	return;
	if( a[p].l==a[p].r )//叶子节点不包含x因子 
	{
		cnt++;
		return;
	}
	int mid=a[p].l+a[p].r>>1;
	if( mid>=l )	ask(p<<1,l,r,x);
	if( mid<r )	ask(p<<1|1,l,r,x);
}
signed main()
{
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)	scanf("%lld",&val[i]);
	build(1,1,n);
	scanf("%lld",&q);
	while( q-- )
	{
		int ok,l,r,x;
		scanf("%d",&ok);
		if( ok==1 )
		{
			scanf("%lld%lld%lld",&l,&r,&x);
			cnt=0;
			ask(1,l,r,x);
			if( cnt<=1 )	puts("YES");
			else	puts("NO");
		}
		else
		{
			scanf("%lld%lld",&l,&x);
			change(1,l,l,x);
		}
	}
}