分块
看到没有写分块的,那我就写一篇分块的题解
这道题很像P4145,都是暴力修改+优化
对于修改操作和查询操作分类讨论:
-
修改
修改很简单,直接单点修改并更新区间lazy标记(区间gcd值)
-
查询
显然,对于区间内不能被x整除的数的个数大于1时显然怎么改也不能符合要求。
所以我们只要查询区间内不能被x整除的数的个数就好了
那么如何把区间gcd值改为不能被x整除的数呢?
我们容易知道,如果区间gcd值 m o d x = 0 mod x=0 modx=0,那么这个区间里的数肯定都能被x整除
如果不等于0,就暴力遍历即可
优化
- 数据量比较大,使用快读
- 将频繁使用的循环变量改为register
- 查询时如果区间内不能被x整除的数的个数已经 > 2 >2 >2,就直接输出NO并return
这样就可以用分块通过本题啦
代码
#include<bits/stdc++.h>
using namespace std;
namespace FAST_IO
{
template<typename T> void read(T &a)
{
a=0;
int f=1;
char c=getchar();
while(!isdigit(c))
{
if(c=='-')
{
f=-1;
}
c=getchar();
}
while(isdigit(c))
{
a=a*10+c-'0';
c=getchar();
}
a=a*f;
}
template <typename T> void write(T a)
{
if(a<0)
{
a=-a;
putchar('-');
}
if(a>9)
{
write(a/10);
}
putchar(a%10+'0');
}
template <typename T> void writeln(T a)
{
write(a);
puts("");
}
}//快读
const int maxn=5e5+999;
int belong[maxn],l[maxn],r[maxn],num,_size;
int n,a[maxn],add[maxn],lazy[maxn];
void build()
{
_size=sqrt(n);
num=n/_size;
if(n%_size)
{
num++;
}
for(int i=1;i<=num;i++)
{
l[i]=(i-1)*_size+1;
r[i]=i*_size;
}
r[num]=n;
for(int i=1;i<=n;i++)
{
FAST_IO::read(a[i]);
belong[i]=i/_size;
if(i%_size)
{
belong[i]++;
}
lazy[belong[i]]=__gcd(lazy[belong[i]],a[i]);
}
}
void update(int pos,int c)
{
int x=belong[pos];
a[pos]=c;
lazy[x]=0;
for(register int i=l[x];i<=r[x];i++)
{
lazy[x]=__gcd(lazy[x],a[i]);
}
}
void ask1(int ls,int rs ,int xt)
{
int ans=0;
int x=belong[ls],y=belong[rs];
register int i,j;
if(x==y)
{
for(i=ls;i<=rs;i++)
{
if(a[i]%xt!=0)
{
ans++;
}
}
}
else
{
for(i=ls;i<=r[x];i++)
{
if(a[i]%xt!=0)
{
ans++;
}
}
if(ans>=2)
{
puts("NO");
return;
}
for(i=x+1;i<=y-1;i++)
{
if(lazy[i]%xt!=0)
{
for(j=l[i];j<=r[i];j++)
{
if(a[j]%xt!=0)
{
ans++;
}
}
if(ans>=2)
{
puts("NO");
return;
}
}
}
for(i=l[y];i<=rs;i++)
{
if(a[i]%xt!=0)
{
ans++;
}
}
}
if(ans>=2)
{
puts("NO");
}
else
{
puts("YES");
}
}
int op,ltt,rtt,x;
signed main()
{
int f;
FAST_IO::read(n);
build();
FAST_IO::read(f);
while(f--)
{
FAST_IO::read(op);
FAST_IO::read(ltt);
FAST_IO::read(rtt);
if(op==1)
{
FAST_IO::read(x);
ask1(ltt,rtt,x);
}
else
{
update(ltt,rtt);
}
}
}