先对所有数质因数分解。显然相同的质因数可以看成一个。这样一个数最多只有 6 个质因数。
维护
时间复杂度O(26×q)。
代码
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 200010
#define M 500010
#define ll long long
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void Read(int& x){
char c=nc();
for(;c<'0'||c>'9';c=nc());
for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
}
char ss[30];
int Len;
inline void Print(ll x){
if(!x)putchar(48);
for(Len=0;x;x/=10)ss[++Len]=x%10;
while(Len)putchar(ss[Len--]+'0');
putchar('\n');
}
ll Ans;
int s,a[N],c[N][20],l[N],p[N],i,j,k,n,m,f[M],num,Res,q,t;
int x,y;
bool b[M];
inline void Init(){
for(i=2;i<=m;i++){
if(!b[i])p[++num]=i;
int t;
for(j=1;j<=num&&(t=p[j]*i)<=m;j++){
b[t]=1;
if(!(i%p[j]))break;
}
}
}
inline void Dfs(int x,int y,int s,bool b){
if(x==l[y]+1){
Res+=(b?1:-1)*f[s];
return;
}
Dfs(x+1,y,s,b);
Dfs(x+1,y,s*c[y][x],b^1);
}
inline void Dfs2(int x,int y,int s,int d){
if(x==l[y]+1){
if(s>1)f[s]+=d;
return;
}
Dfs2(x+1,y,s,d);
Dfs2(x+1,y,s*c[y][x],d);
}
inline void Update(int x,int d){
if(a[x]==1){
Ans+=d*(k+t);t+=d;
if(d==-1)Ans++;
return;
}
Res=0;
Dfs(1,x,1,0);
Ans+=t*d;
Ans+=(k-Res)*d;
Dfs2(1,x,1,d);
k+=d;
}
int main(){
Read(n);Read(q);m=2;
for(i=1;i<=n;i++)Read(a[i]),m=max(m,a[i]);
Init();
for(i=1;i<=n;i++){
x=a[i];s=sqrt(x);
for(j=1;p[j]<=s;j++)
if(!(x%p[j])){
c[i][++l[i]]=p[j];x/=p[j];
while(!(x%p[j]))x/=p[j];
}
if(x>1)c[i][++l[i]]=x;
}
memset(b,0,sizeof(b));
while(q--){
Read(x);
if(!b[x])Update(x,1),b[x]=1;
else Update(x,-1),b[x]=0;
Print(Ans);
}
return 0;
}
本文介绍了一种利用质因数分解处理特定数论问题的方法,通过维护每个数作为多少个数的因数的状态,实现了高效更新与查询。算法的时间复杂度为O(2^6*q),适用于需要频繁进行数论操作的场景。

1373

被折叠的 条评论
为什么被折叠?



