题目大意:

  求l~r中有多少数与x互质,带单点修改

分析:

  两个30的部分分很好打:

    ·n<=1000暴力O(nq)就好了

    ·$a_i<=100$用树状数组维护每个x的前缀和就好了

  100分做法有两种,一种是莫比乌斯反演(我不会),还有一种就是bitset乱搞

  我们先筛法筛出所有质数(大概不到10000个)然后对于每个质数建立一个bitset,表示对于第i个数在有第j个质数这个质因子

  求有多少数与x互质转换为有多少数与x不互质就好了

  对于每次询问把所有x的质因子找出来然后把这些数的bitset或起来再用类似前缀和的方法维护即可

  时间复杂度$O(\frac{n*Q*logn}{32})$显然跑不满,所以卡一卡就过了(跑的比莫比乌斯反演快)

代码:(这里把两种部分分的打法也都写上了)

 #pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
inline int read(){
int ans=,f=;char chr=getchar();
while(!isdigit(chr)){if(chr=='-')f=-;chr=getchar();}
while(isdigit(chr)) {ans=(ans<<)+(ans<<)+chr-;chr=getchar();}
return ans*f;
}const int M = 5e4+;
int n,m,a[M],Q,ans,gcd[][];
struct P{
int s[M];
void Update(int x,int a){for(;x<=n;x+=lowbit(x)) s[x]+=a;}
int Query(int x){int res=;for(;x;x-=lowbit(x)) res+=s[x];return res;}
}t[];
//-------------------------------------------------第一个30pts --------------------------------------------------
inline void Solve_1(){//n*Q<=1000000
while(Q--){
int opt=read(),x;
if(opt==) x=read(),a[x]=read();
else{
int l=read(),r=read();
x=read();ans=;
for(int i=l;i<=r;i++)
if(__gcd(x,a[i])==)
++ans;
printf("%d\n",ans);
}
}
}
//---------------------------------------第二个30pts -----------------------------------------------------
inline void Solve_2(){//Ai<=100
for(int i=;i<=;++i)
for(int j=;j<=;++j)
gcd[i][j]=__gcd(i,j);
for(int i=;i<=;i++)
for(int j=;j<=n;j++)
if(gcd[i][a[j]]==)
t[i].Update(j,);
while(Q--){
int opt=read();
if(opt==){
int x=read(),y=read(),tt=a[x];
a[x]=y;
for(int i();i<=;++i){
if(gcd[a[x]][i]!=&&gcd[tt][i]==)
t[i].Update(x,-);
if(gcd[a[x]][i]==&&gcd[tt][i]!=)
t[i].Update(x,);
}
}else{int l=read(),r=read(),x=read();
printf("%d\n",t[x].Query(r)-t[x].Query(l-));
}
}
}bitset<M>s[],now;
int v[M*],pri[M*],tot;
//----------------------------------------通解--------------------------------------------
inline void Get_Pri(){
for(int i=;i<=;i++){
if(!v[i]) v[i]=i,pri[++tot]=i;
for(int j=;j<=tot;j++){
if(pri[j]>/i||pri[j]>v[i]) break;
v[i*pri[j]]=pri[j];
}
}
}
inline void Update(int pos,int x,int y){
int i=;
while(){
if(pri[i]*pri[i]>x) break;
if(x%pri[i]==){
s[i][pos]=y;
while(x%pri[i]==) x/=pri[i];
}i++;
}if(x>)s[lower_bound(pri+,pri+tot+,x)-pri][pos]=y;
}
inline void Solve(){
Get_Pri();
for(int i=;i<=n;i++) Update(i,a[i],);
while(Q--){
int opt=read();
if(opt==){
int x=read(),y=read();
Update(x,a[x],),Update(x,y,);
a[x]=y;
}else{
int l=read(),r=read(),x=read();
int i=;now=;
while(){
if(pri[i]*pri[i]>x) break;
if(x%pri[i]==){
now|=s[i];
while(x%pri[i]==) x/=pri[i];
}i++;
}if(x>) now|=s[lower_bound(pri+,pri+tot+,x)-pri];
int Ans=r-l+-(now>>l).count()+(now>>(r+)).count();
printf("%d\n",Ans);
}
}
}
int main(){
freopen("gcd.in","r",stdin);
freopen("gcd.out","w",stdout);
n=read();
for(int i=;i<=n;++i) a[i]=read();
Q=read();
// if(n*Q<=1000000) Solve_1();
// else Solve_2();
Solve();
return ;
}

最新文章

  1. @Column
  2. 开源项目GitHub
  3. javascript call与apply关键字的作用
  4. 使用jsvc启动tomcat
  5. Android入门开发之SD卡读写操作(转)
  6. 迭代接口的IEnumerator
  7. 使用dbms_system追踪其它session
  8. logback.xml_appender配置
  9. c语言趣味
  10. Win7 64位系统上配置使用32位的Eclipse(转)
  11. learn C on the mac 读后笔记
  12. 删除cygwin
  13. HTTP代理浅说
  14. 代理模式与java中的动态代理
  15. onCreate和onStart谁的开销大?
  16. Docker:dockerfile构建php项目 [八]
  17. scrapy_redis项目配置
  18. C++拷贝构造函数(深拷贝&amp;浅拷贝)
  19. Linux 服务器命令,持续更新……
  20. Spring+SpringMVC+Mybatis整合(二)

热门文章

  1. Spring-Security (学习记录四)--配置权限过滤器,采用数据库方式获取权限
  2. java基础编程题(2)
  3. ZK4字命令
  4. 2019 牛客多校第一场 A Equivalent Prefixes
  5. 当class有多个class属性时截取操作
  6. 本地 win7 与虚拟机Centos7 ping互通和Centos7 上网设置
  7. Restoring Road Network Floyd
  8. 数组模拟stack
  9. codis 使用
  10. PKPM快捷键