bzoj3739 DZY loves math VIII 莫比乌斯函数

来源:互联网 发布:3g和4g网络的区别大吗 编辑:程序博客网 时间:2024/05/21 10:55

       智商太低到现在还不会用μ函数做题。。膜拜了Claris的题解(其实主要是去看代码的)。

       显然当gcd(i,j)>0时,对答案是没有贡献的的,因此化简原式得到:

       

       如果令

       我们可以发现f(i,d)=f(i-d,d)+μ(i)。然后可以暴力枚举因数d,最后更新f(i,d)(实际上只需要保存后面一维即可),然后就好了。

AC代码如下:

#include<iostream>#include<cstdio>#define N 10000005using namespace std;int n,cnt,mu[N],c[1000005],ask[1005],f[N],a[15],p[N],sum[N];void pfs(){int i,j,k; mu[1]=1;for (i=2; i<=n; i++){if (!p[i]){ p[i]=c[++c[0]]=i; mu[i]=-1; }for (j=1; j<=c[0] && (k=i*c[j])<=n; j++){p[k]=c[j];if (i%c[j]) mu[k]=-mu[i];else{ mu[k]=0; break; }}}}int dfs(int k,int x,int v){if (k>cnt){f[x]+=v; return mu[x]*f[x];}return dfs(k+1,x*a[k],v)+dfs(k+1,x,v);}int main(){int cas,i; scanf("%d",&cas);for (i=1; i<=cas; i++){scanf("%d",&ask[i]); n=max(n,ask[i]);}pfs();for (i=1; i<=n; i++){sum[i]+=sum[i-1];if (mu[i]){cnt=0; int x=i;for (; x>1; x/=p[x]) a[++cnt]=p[x];sum[i]+=mu[i]*dfs(1,1,mu[i]);}}for (i=1; i<=cas; i++) printf("%d\n",sum[ask[i]]);return 0;}


by lych

2016.2.23

0 0
原创粉丝点击