这题其实求的是x的倍数个数是否大于1,大于1肯定不行,否则可以
另外一点,如果区间gcd不能整除x,那么必有至少一个数不是x的倍数,不然gcd会更大
因此我们只要暴力维护并且在发现不止一个的时候及时退出,这样复杂度就可以
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=1e6+10; const int mod=1e9+7; int gcd(int a,int b){ return b?gcd(b,a%b):a; } struct node{ int l,r; int d; }tr[N<<2]; int a[N]; int cnt; void pushup(int u){ tr[u].d=gcd(tr[u<<1].d,tr[u<<1|1].d); } void build(int u,int l,int r){ if(l==r){ tr[u]={l,r,a[l]}; } else{ tr[u]={l,r}; int mid=l+r>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); pushup(u); } } void modify(int u,int l,int x){ if(tr[u].l==tr[u].r){ tr[u].d=x; return ; } int mid=tr[u].l+tr[u].r>>1; if(l<=mid) modify(u<<1,l,x); else modify(u<<1|1,l,x); pushup(u); } void query(int u,int l,int r,int x){ if(cnt>1) return ; if(tr[u].l==tr[u].r){ cnt++; return ; } int mid=tr[u].l+tr[u].r>>1; if(l<=mid&&(tr[u<<1].d%x)) query(u<<1,l,r,x); if(r>mid&&(tr[u<<1|1].d%x)) query(u<<1|1,l,r,x); } int main(){ ios::sync_with_stdio(false); int n; cin>>n; int i; for(i=1;i<=n;i++) cin>>a[i]; build(1,1,n); int q; cin>>q; while(q--){ int opt; cin>>opt; if(opt==1){ int l,r,x; cin>>l>>r>>x; cnt=0; query(1,l,r,x); if(cnt>1){ cout<<"NO"<<endl; } else{ cout<<"YES"<<endl; } } else{ int l,x; cin>>l>>x; modify(1,l,x); } } return 0; }