zoukankan      html  css  js  c++  java
  • BZOJ#4804. 欧拉心算


    4804: 欧拉心算

    Time Limit: 15 Sec  Memory Limit: 256 MB
    Submit: 508  Solved: 298
    [Submit][Status][Discuss]

    Description

     给出一个数字N

    Input

    第一行为一个正整数T,表示数据组数。
    接下来T行为询问,每行包含一个正整数N。
    T<=5000,N<=10^7

    Output

    按读入顺序输出答案。

    Sample Input

    1
    10

    Sample Output

    136
     
     

    problem:

    solution:   

                        

    枚举gcd:  

                

    套路求gcd==1:

                

    根据公式二可得:

                

    枚举di:

                 

    现在就要预处理出:

                      

     
    发现φ和μ都是积性函数,所有h也是积性函数,但不是完全积性,所有在线性筛时我们要分类讨论: 
     
       if(i*prime[j]>N) break;
                vis[i*prime[j]]=1;
                if(i%prime[j]==0)
                {
                    if(i/prime[j]%prime[j]==0) h[i*prime[j]]=h[i]*prime[j];//a,b不互质
                    else h[i*prime[j]]=h[i/prime[j]]*(long long)(prime[j]-1)*(prime[j]-1);//根据积性函数性质
                    break;
                }
                h[i*prime[j]]=h[i]*h[prime[j]];

     附上代码:
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e7+12;
    int prime[N],cnt,vis[N];
    long long h[N],ans;
    void getmu()
    {
        h[1]=1;
        for(int i=2;i<=N;i++)
        {
            if(!vis[i]) prime[++cnt]=i,h[i]=i-2;
            for(int j=1;j<=cnt;j++)
            {
                if(i*prime[j]>N) break;
                vis[i*prime[j]]=1;
                if(i%prime[j]==0)
                {
                    if(i/prime[j]%prime[j]==0) h[i*prime[j]]=h[i]*prime[j];
                    else h[i*prime[j]]=h[i/prime[j]]*(long long)(prime[j]-1)*(prime[j]-1);
                    break;
                }
                h[i*prime[j]]=h[i]*h[prime[j]];
            }
        }
        for(int i=2;i<=N;i++) h[i]=h[i-1]+h[i];
    }
    
    int main()
    {
    //    freopen("a.in","r",stdin);
        getmu();
        int T;scanf("%d",&T);
        while(T--)
        {
            int n;
            scanf("%d",&n);
            int pos;
            ans=0;
            for(int i=1;i<=n;i=pos+1)
            {
                pos=n/(n/i);
                ans+=(long long)(n/i)*(n/i)*(h[pos]-h[i-1]);//注意long long
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }

  • 相关阅读:
    创建索引
    列出所有的索引
    查看集群节点api
    集群健康检查api
    mapping 映射
    Elasticsearch 版本控制
    四种常见的 POST 提交数据方式
    HttpPost 传输Json数据并解析
    基本概念
    信用卡年轻消费群体数据分析和洞察报告
  • 原文地址:https://www.cnblogs.com/Heey/p/9098511.html
Copyright © 2011-2022 走看看