D. Bash and a Tough Math Puzzle
记录区间最大公倍数,记录需要修改几个才能是最大公倍数为x,大于1 输出no其余yes
优化,当修改值等于2时直接返回
代码
#include <bits/stdc++.h>
using namespace std;
const int N =5e5 +10 ;
struct node
{
int l , r ;
int g;
}tr[N * 4 ] ;
int res ;
int n , m ;
int w[N] ;
int q ;
int gcd(int a,int b) {return b>0 ? gcd(b,a%b):a;}
void push_up(int u )
{
tr[u].g = gcd(tr[u << 1 ].g , tr[u << 1 |1 ].g ) ;
}
void build(int u , int l , int r )
{
if(l == r )
{
tr[u] = {l , r , w[l]} ;
return ;
}
tr[u] = {l , r } ;
int mid = l + r >> 1 ;
build(u << 1 , l , mid ) , build(u << 1 | 1 , mid + 1 , r ) ;
push_up(u) ;
}
void query(int u , int l, int r , int z )
{
if(res > 1 ) return ;
if(tr[u].l >= l && tr[u].r <= r )
{
if(tr[u].g % z == 0 ) return ;
if(tr[u].g % z != 0 && tr[u].l == tr[u].r )
{
res ++;
return ;
}
else
{
query(u << 1 , l , r , z ) ;
query(u <<1 | 1 , l , r ,z ) ;
}
}
else
{
int mid = tr[u].l + tr[u].r >> 1 ;
if(l <= mid ) query(u << 1 , l , r , z ) ;
if(r > mid ) query(u << 1 | 1 , l , r , z ) ;
}
}
void modify(int u , int v , int k)
{
if(tr[u].l == tr[u].r )
{
tr[u].g = k ;
return ;
}
int mid = tr[u].l + tr[u].r >> 1 ;
if(v <= mid ) modify(u << 1 , v , k );
else modify(u <<1 | 1 , v , k ) ;
push_up(u) ;
}
int main()
{
scanf("%d",&n);
for(int i =1 ;i <= n ; i ++ ) scanf("%d", &w[i]) ;
build(1 , 1 , n ) ;
int op ;
scanf("%d" , &m) ;
int l , r ,x, k ;
while(m -- )
{
scanf("%d" , &op) ;
if(op ==1)
{
scanf("%d%d%d" , &l,&r,&k);
res = 0 ;
query(1 , l , r , k ) ;
if(res <2 ) printf("YES\n") ;
else printf("NO\n");
}
else
{
scanf("%d%d" , &x , &k) ;
modify(1 ,x , k ) ;
}
}
return 0 ;
}