• hdu6069 Counting Divisors 晒区间素数


    /**
    题目:hdu6069 Counting Divisors
    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6069
    题意:求[l,r]内所有数的k次方的约数个数之和。
    
    思路:
    用(1+e1)*(1+e2)*...*(1+en)的公式计算约数个数。
    素数筛出[l,r]内的素因子,然后直接计算结果。(一开始我用vector存起来,之后再处理,结果超时,
    时间卡的很紧的时候,vector也会很占用时间。)
    
    
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<map>
    #include<vector>
    #include<queue>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef pair<int,int> P;
    typedef long long LL;
    const int INF = 0x3f3f3f3f;
    const int mod = 998244353;
    const int maxn = 1e6+10;
    bool is_prime_small[maxn];
    vector<int> v[maxn];
    int prime[maxn], z;
    LL value[maxn], cnt[maxn];
    void init()
    {
        for(int i = 2; i<=1000000; i++) is_prime_small[i] = true;
        z = 0;
        for(int i = 2; i<=1000000; i++){
            if(is_prime_small[i]){
                z++;
                prime[z] = i;
            }
            for(int j = 1; j <= z; j++){
                if((LL)i*prime[j]>=1000000){
                    break;
                }
                is_prime_small[i*prime[j]] = false;
                if(i%prime[j]==0) break;
            }
        }
    }
    void segment_sieve(LL a,LL b,LL k)  //[a,b)
    {
    
        for(int i = 0; i < b-a; i++) value[i] = i+a, cnt[i] = 1;
        int num;
        for(int i = 1; (LL)prime[i]*prime[i]<b&&i<=z; i++){
            for(LL j = max((LL)prime[i],(a+prime[i]-1)/prime[i])*prime[i]; j < b; j+=prime[i]){
                num = 0;
                while(value[j-a]%prime[i]==0){
                    num++; value[j-a]/=prime[i];
                }
                cnt[j-a] = cnt[j-a]*(num*k+1)%mod;
            }
        }
    }
    LL solve(LL a,LL b,LL k)
    {
    
        LL ans = 0;
        for(int i = 0; i < b-a; i++){
            if(value[i]>1){
              cnt[i] = cnt[i] * (k+1) % mod;
            }
            ans = (ans + cnt[i])%mod;
        }
    
        return ans;
    }
    int main()
    {
        int T;
        cin>>T;
        init();
        LL l, r, k;
        while(T--){
            scanf("%lld%lld%lld",&l,&r,&k);
            if(l==r&&l==1){
                printf("1
    "); continue;
            }
            int flag = 0;
            if(l==1){
                l++;
                flag = 1;
            }
            segment_sieve(l,r+1,k);
            printf("%lld
    ",(solve(l,r+1,k)+flag)%mod);
        }
        return 0;
    }
  • 相关阅读:
    springboot 实现 aop
    使用@import导入实现了ImportBeanDefinitionRegistrar接口的类,不能被注册为bean
    Spring Boot 动态数据源(多数据源自动切换)
    springboot2动态数据源的绑定
    三分钟学会@Autowired@Qualifier@Primary注解
    java复制文件的4种方式
    五款最好的免费同步软件
    springboot2多数据源完整示例
    WebSocket 结合 Nginx 实现域名及 WSS 协议访问
    Spring的注解@Qualifier注解
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/7283884.html
Copyright © 2020-2023  润新知