[Codeforces 547C] Mike And Foam 莫比乌斯反演

来源:互联网 发布:anywhere软件源 编辑:程序博客网 时间:2024/06/06 07:01

F(i)=sigma(i|d,f(d))=C(g(i),2),g(i)是现在的i的倍数的数量,f(i)=sigma(i|d,miu(d/i)*F(d))所求即为f(1)的值.动态维护g(i)即可.

Code:

#include <bits/stdc++.h>#define ll long longusing namespace std;ll ans=0;int n,q,id;int miu[500005],pri[100005],cnt=0;bool isp[500005];bool vis[200005];int a[200005];ll g[500005];inline void gmiu(){miu[1]=1;for (int i=2;i<=500000;i++){if (!isp[i]) {pri[++cnt]=i;miu[i]=-1;}for (int j=1;j<=cnt&&pri[j]*i<=500000;j++){isp[i*pri[j]]=1;if (i%pri[j]==0) {miu[i*pri[j]]=0;break;}miu[i*pri[j]]=miu[i]*(-1);}}}void add(int num,int del){int i,t;ll prv,rev;for (i=1;i*i<=num;i++){if (num%i==0){t=i;prv=miu[t]*g[t]*(g[t]-1)/2;g[t]+=del;rev=miu[t]*g[t]*(g[t]-1)/2;ans-=prv;ans+=rev;if (i!=num/i){t=num/i;prv=miu[t]*g[t]*(g[t]-1)/2;g[t]+=del;rev=miu[t]*g[t]*(g[t]-1)/2;ans-=prv;ans+=rev;}}}printf ("%lld\n",ans);}int main (){gmiu();int i;scanf ("%d%d",&n,&q);for (i=1;i<=n;i++){scanf ("%d",&a[i]);}for (i=1;i<=q;i++){scanf ("%d",&id);if (!vis[id]) {vis[id]=1;add(a[id],1);}else {vis[id]=0;add(a[id],-1);}}return 0;}


阅读全文
1 0