bzoj 3739 DZY loves math VIII

来源:互联网 发布:数据恢复软件正式版 编辑:程序博客网 时间:2024/06/05 04:53

3739: DZY loves math VIII

Time Limit: 25 Sec Memory Limit: 512 MB
Submit: 318 Solved: 50
[Submit][Status][Discuss]
Description

在XYZ的dzy loves math6问世后,dzy一直觉得这道题答案太大,一点都不优美,于是他随手在外面套上一个μ。同时,他又觉得输入两个数实在太麻烦,于是题目变成了,你能解决这个问题吗?

Input

第一行一个整数T表示询问组数,接下来T行每行一个整数n。

Output

对于每一个询问输出一行表示答案

Sample Input

1

2

Sample Output

0

HINT

T<=10^3 n<=10^7

Source


【分析】

稍微想一下μ 的定义,你会发现这题其实能化简…
gcd(i,j)>1的情况下μ 一定为0,质因子一定有平方…
所以直接考虑i,j 互质的情况,即gcd(i,j)=1 
所以原式为

 n i=1  i j=1 μ(ij) 

然后繁衍繁衍,乱搞一发,暴搜+nlogn=O(能过)
所以这题就是考你怎么求一个鬼畜的式子还不TLE


【代码】

//bzoj 3739 DZY loves math VIII#include<cstdio>#include<cstring>#include<iostream>#define N 10000000#define ll long long#define fo(i,j,k) for(i=j;i<=k;i++)using namespace std;const int mxn=10000005;int n,m,T,cnt;int vis[mxn],pri[mxn],miu[mxn],sum[mxn],f[mxn],a[mxn];inline int read(){    int x=0;char ch=getchar();    while(ch<'0'||ch>'9') ch=getchar();    while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();    return x;}inline void init(){    int i,j;    miu[1]=1;    fo(i,2,N)    {        if(!vis[i]) vis[i]=pri[++pri[0]]=i,miu[i]=-1;        for(j=1;j<=pri[0] && (ll)i*pri[j]<=N;j++)        {            vis[i*pri[j]]=pri[j];            if(i%pri[j]==0) break;            miu[i*pri[j]]=-miu[i];        }    }}inline int dfs(int k,int x,int v){    if(k>cnt)    {        f[x]+=v;return miu[x]*f[x];    }    return dfs(k+1,x*a[k],v)+dfs(k+1,x,v);}int main(){    init();    int i,j;    fo(i,1,N)    {        sum[i]+=sum[i-1];        if(miu[i])        {            cnt=0;            for(int x=i;x>1;x/=vis[x])              a[++cnt]=vis[x];            sum[i]+=miu[i]*dfs(1,1,miu[i]);        }    }    T=read();    while(T--)    {        n=read();        printf("%d\n",sum[n]);    }    return 0;}
原创粉丝点击