zoukankan      html  css  js  c++  java
  • T3

    T3 题解

    题目:

    题目背景

    • 致远星舰队旗舰——“养生壶”号上(别问为啥,外星人的语言习惯)

    • 装着全致远星最先进的密码保护系统

    • 你作为OI星最强的间谍——(代号:映山红)

    • 偷偷来到了这艘战舰上

    • 你经历重重历险终于来到了战舰的总控室

    • 密码系统作为高级货当然不是静态的

    • 它描绘的是这样一个问题:

    • 计算满足:1到n内,gcd(x,y)为素数的数对有多少。

    • 现在帝国的护卫队已经发现了你的踪迹

    • 你能够使用的就是一台性能与公元$2000$年电脑性能几乎无差的掌上解码器

    • 你需要在尽可能短的时间内算出问题的答案

    题目描述

    • 求1≤x,y≤n中 , 满足:gcd(x,y)为素数的数对有多少。

    输入格式

    • 一行一个数n

    输出格式

    • 一行一个数 , 表示满足条件的数对数量

    输入输出样例

    输入 #1

    4

    输出 #1

    4

    输入 #2

    12

    输出 #2

    39

    说明/提示

    • 对于10%的数据,保证n≤10

    • 对于50%的数据,保证n≤105

    • 对于100% 的数据 , 保证n≤107

    • 数据随机生成 , 大佬们可以暴力踩标程 (bushi)

    翻译一下题意:给定一个正整数n,求1≤x,y≤n中满足gcd(x,y)为素数的数对有多少。

    思路:

    既然gcd(x,y)是一个质数,那么我们可以认为,如果我们假设gcd(x,y)的值为p,则gcd(x/p,y/p)的值一定为1。既然这样,那么我们就可以先求出1到n中所有的素数,然后再依次求出对于1到n/p[i]的x和y,满足gcd(x,y)=1的素数的个数。

    我们在求对于每一对1≤x,y≤n/p[i]的x和y,满足gcd(x,y)=1的数对的对数时,不妨设x≤y(如果不满足则交换x和y的顺序)。

    我们考虑对于每一个确定的y,因为x≤y,所以对于每一对1≤x,y≤n/p[i]的x和y,当我们给定一个确定的y值的时候,满足gcd(x,y)=1的数对的对数就等于φ(y)的值。

    因而,对于每一对1≤x,y≤n/p[i]的x和y,满足gcd(x,y)=1的数对的对数就等于∑(i=1->n/p[i])φ(i)。

    这样我们就可以得出这道题的完整思路:

    我们先跑一遍筛素数(这里用线性筛即可),筛出1到n之间的所有质数,以及求出1到n之间每个数i的φ(i)的值,然后再枚举质数,求出对于1到n的每一个质数p[i],它所对应的∑(i=1->n/p[i])φ(i)的值,最后再一次进行累加求和。

    完整代码(by 巨佬HWH):

     1 #include<cstdio>
     2 #define ll long long
     3 using namespace std;
     4 
     5 const ll N=1e7+9;
     6 ll pr[N],ph[N];
     7 
     8 int main()
     9 {
    10     register ll n,i,j,k=0,p;
    11     register long long s=0,t=0;
    12     
    13     scanf("%lld",&n);
    14     
    15     ph[1]=1;
    16     for(i=2;i<=n;++i)
    17     {    
    18         if(!ph[i]) pr[++k]=i,ph[i]=i-1;
    19         for(j=1;p=i*pr[j],p<=n&&j<=k;++j)
    20         {
    21             if(i%pr[j]==0)
    22             {
    23                 ph[p]=ph[i]*pr[j];
    24                 break;
    25             }
    26             else ph[p]=ph[i]*ph[pr[j]];
    27         }
    28     }
    29     
    30     for(i=1,j=k;j;--j)
    31     {
    32         for(p=n/pr[j];i<=p;++i)t+=ph[i];
    33         s+=t;
    34     }
    35     
    36     printf("%lld",(s<<1)-k);
    37     return 0;
    38 }
  • 相关阅读:
    2.NET Core设定数据库种子
    1.ASP.NET Core 中向 Razor Pages 应用添加模型
    获取文件夹目录下的文件信息
    dataGridView读写文本
    C# winform 启动外部程序
    netcore访问本地磁盘
    c#利用定时器自动备份数据库(mysql)
    c#mysql数据库备份还原
    Linux之旅(二)
    Linux之旅
  • 原文地址:https://www.cnblogs.com/qianr/p/13402394.html
Copyright © 2011-2022 走看看