多校10 hdu 6434 Problem I. Count (前缀和化简+欧拉函数)

题目链接:哆啦A梦传送门

题解:

参考博客:http://acm.hdu.edu.cn/showproblem.php?pid=6434

\sum_{i=1}^{n}\sum_{j=1}^{i-1} {gcd(i+j,i-j)=1}

我们令 a=i-j,那么由 j<=i-1,得 i-j>=1,再有 j>=1,的 i-j<=i-1

\sum_{i=1}^{n}\sum_{a=1}^{i-1} {gcd(2*i-a,a)=1}

由辗转相除法可得下式。

{\color{Red} \sum_{i=1}^{n}\sum_{a=1}^{i-1} {gcd(2*i,a)=1}}

 

故题目就变成求 与i互质的数(小于i)有多少个?但题目是求2*i的,

所以当i为偶数时,与i互质的数一定是奇数,那么 {\color{Red} \varphi (2*i)=\varphi (i)}

当i为奇数时,与i互质的偶数有{\color{Red} \varphi (i)/2}个,那么{\color{Red} \varphi (2*i)=\varphi (i)/2},最后我们处理下前缀和就行了。

 

#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;
typedef long long LL;
const int maxn=2e7+10;

int phi[maxn],pri[maxn],tot;
bool vis[maxn];

void init()
{
    memset(vis,0,sizeof(vis));
    tot=0;
    int n=maxn-5;
    phi[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!vis[i]){
            phi[i]=i-1;
            pri[++tot]=i;
        }
        for(int j=1;j<=tot;j++)
        {
            int x=pri[j];
            if(i*x>n) break;
            vis[i*x]=1;
            if(i%x==0){
                phi[i*x]=phi[i]*x;break;
            }
            else{
                phi[i*x]=phi[i]*phi[x];
            }
        }
    }
}

LL sum[maxn];
int main()
{

    init();
    int n,ncase;

    scanf("%d",&ncase);
    sum[0]=sum[1]=0;

    for(int i=2;i<=20000000;i++)
    {
        if(i%2==1) sum[i]=sum[i-1]+phi[i]/2;
        else sum[i]=sum[i-1]+phi[i];
    }

    while(ncase--)
    {
        scanf("%d",&n);

        printf("%lld\n",sum[n]);
    }
    return 0;



}




 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值