zoukankan      html  css  js  c++  java
  • ACM-ICPC 2018 南京赛区网络预赛 J sum (找一个数拆成两个无平方因子的组合数)

    题目大意:就是找一个数拆成两个无平方因子的组合数,然后求个前缀和  ;

    分析:运用筛法的思想 , 

     因为有序对是由两个合法的数字组成的,所以只要保证第一个数合法,第二个数也合法就行,找出合法的第二个数字的个数就可以用sum前缀和来算,所以L就是第一个数,R=n/L就是最大的第二个数,这里又规定了第二个数从L+1开始,所以sum[R]-sum[L]就是L+1~R合法数字的个数

    sum[i] 表示的是小于等于i 的合法因子数 , sum[R]-sum[L] , 就是表示因子大于L,小于等于R,的个数

     L代表第一个数字
    乘2是因为比如说枚举到(2,6)的时候也要把(6,2)加进去,而因为L只到sqrt(n),所以(6,2)是不会枚举到的,所以要在这里计算进去,加1就是加上比如(2,2),(3,3)等两边数字相同的情况。
     
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    
    const int UP = 2e7 + 5;
    bool can[UP];
    int sum[UP];
    
    void constant() {
        memset(can, true, sizeof(can));
        int u = sqrt(UP+0.5);
        for(int i = 2; i <= u; i++) {
            int v = i * i;
            for(int t = v; t < UP; t += v) can[t] = false;
        }
        for(int i = 1; i < UP; i++) {
            sum[i] = sum[i-1] + 1;
            if(!can[i]) sum[i]--;
        }
    }
    
    int main() {
        constant();
        int T, n;
        scanf("%d", &T);
        while(T--) {
            scanf("%d", &n);
            int u = sqrt(n+0.5);
            long long ans = 0;
            for(int L = 1; L <= u; L++) {
                if(!can[L]) continue;
                int R = n / L;
                //printf("L = %d  sum = %d
    ", L, sum[R] - sum[L-1]);
                ans += (sum[R] - sum[L]) * 2 + 1;
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    [译]GLUT教程
    [译]GLUT教程
    [译]GLUT教程
    strlen,_conntof,sizeof
    《const限定符的使用》
    设备资源管理系统-JFreeChart
    设备资源管理系统-jxl报表
    设备资源管理系统-poi报表
    设备资源管理系统-分页
    设备资源管理系统-日志管理
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/9581091.html
Copyright © 2011-2022 走看看