201. 可见的点 线性筛法求 欧拉函数 1到N中与N互质的数的个数

题目

在这里插入图片描述

题解思路

欧拉函数是小于或等于n的正整数中与n互质的数的数目
phi[ 1 ] = 1
我们可以在筛法的中间穿插欧拉函数的求法。
很显然 在筛法 首先出现的素数们的欧拉函数值肯定是 i - 1 ,它一定对前面出现的数都互质。(因为它能组成的合数还没出现)
欧拉筛是用之前出现的素数来筛这个数组合成的合数,当发现是素数是这个数的最小质因子的时候就break。
在这里插入图片描述
运用这个公式我们能递推出合数的欧拉函数转移方程。
下面的题解提供了推导过程。

然后回到这题

斜率y/x必然互质 ,这样才能保证他们不会出现相同的点的情况。
坑点,x y 可以为0 。
这样我们让 1 0 0 1 去走 x y 轴 再让 1 1 走 对称轴
这样剩下的就是 对 2 到 N 欧拉函数值求和 * 2 了

欧拉函数详解
题解以及欧拉函数简介

AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;

const  int  INF =  0x3f3f3f3f;
const  int  N = 200100;
bool st[N] ;
int prm[N] ;
int hi[N] ;
int cnt ;

void in (int  n )
{
    cnt = 1 ;
    st[1] = 1 ;
    hi[1] = 1 ;
    for (int i = 2 ; i <= n ; i++ )
    {
        if ( ! st[i] )
        {
            prm[cnt] = i ;
            cnt++ ;
            hi[i] = i - 1 ;
        }
        for (int j = 1 ; i*prm[j] <= n ; j++ )
        {
            st[i*prm[j]] = 1 ;
            if ( i % prm[j] == 0 )
            {
                hi[i*prm[j]] = hi[i] * prm[j] ;
                break;
            }
            hi[ i*prm[j] ]  = hi[i] * ( prm[j] - 1 ) ;
        }
    }
}


int main ()
{
    ios::sync_with_stdio(false);
    int T ;
    in(1010);
    cin >> T;
    int tt = 1 ;
    while( T-- )
    {
        int n ;
        int ans = 0 ;
        cin >> n ;
        for (int i = 1 ; i <= n ; i++ )
        {
            ans += hi[i] ;
           // cout << hi[i] <<"   ";
        }
        cout<< tt << " " << n << " " << 2*ans + 1  << "\n";
        tt++;
    }
    return 0 ;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值