【uestc 1425 D Farey Sequence Length】+ 打表

D  Farey Sequence Length
Given a positive integer, N, the sequence of all fractions a / b with (0 < a  b), (1 < b  N) and a and b
relatively prime, listed in increasing order, is called the Farey Sequence of order N.
For example, the Farey Sequence of order 6 is:
0/1, 1/6, 1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5, 5/6, 1/1
For this problem, you will write a program to compute the length of the Farey sequence of order N
(input).
Input
The first line of input contains a single integer P, (1  P  10000), which is the number of data sets that
follow. Each data set should be processed identically and independently.
Each data set consists of a single line of input. It contains the data set number, K, followed by the
order N, N (2 <= N <= 10000), of the Farey Sequence whose length is to be found.
Output
For each data set there is a single line of output. The single output line consists of the data set
number, K, followed by a single space followed by the length of the Farey Sequence as a decimal
integer.
Sample Input Sample Output
4
1 6
2 15
3 57
4 9999
1 13
2 73
3 1001
4 30393487

直接判断互质会超时,换个方式,只要和这个数有公约数就排除,一个数和本身肯定不互质(1除外),初始化dp[i] = i - 1,然后从1 ~ 10000遍历,依次查找 i 的约数a和,者大于等于 i + a的都和i不互质,最后 i 本身有可能是质数~~时间复杂度O(10^8)

AC代码:

#include<cstdio>
#include<cstring>
using namespace std;
int dp[10010],vis[10010];
int main()
{
    int T,K,N;
    scanf("%d",&T);
    for(int i = 1; i <= 10000; i++) dp[i] = i - 1;dp[1] = 2;
    for(int i = 2; i <= 10000; i++){
            memset(vis,0,sizeof(vis));
        for(int j = 2; j * j <= i; j++){
            if(i % j == 0){
            int p = i / j;
              for(int k = i + j; k <= 10000; k += j)
                   if(!vis[k]) vis[k] = 1,dp[k]--;
              for(int k = i + p; k <= 10000; k += p)
                   if(!vis[k]) vis[k] = 1,dp[k]--;
        }
        }
        for(int j = i + i; j <= 10000; j += i) if(!vis[j]) vis[j] = 1,dp[j]--;
    }
    int ans = 0;
    for(int i = 1 ; i <= 10000; i++) dp[i] += ans,ans = dp[i];
    while(T--){
        scanf("%d %d",&K,&N);
        printf("%d %d\n",K,dp[N]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值