zoukankan      html  css  js  c++  java
  • hdu 6069 Counting Divisors 筛法

    Counting Divisors

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)


    Problem Description
    In mathematics, the function d(n) denotes the number of divisors of positive integer n.

    For example, d(12)=6 because 1,2,3,4,6,12 are all 12's divisors.

    In this problem, given l,r and k, your task is to calculate the following thing :

    (i=lrd(ik))mod998244353

     
    Input
    The first line of the input contains an integer T(1T15), denoting the number of test cases.

    In each test case, there are 3 integers l,r,k(1lr1012,rl106,1k107).
     
    Output
    For each test case, print a single line containing an integer, denoting the answer.
     
    Sample Input
    3 1 5 1 1 10 2 1 100 3
     
    Sample Output
    10 48 2302
     
    Source

    官方题解:

      唯一分解定理

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<set>
    #include<map>
    #include<stdlib.h>
    #include<time.h>
    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define pi (4*atan(1.0))
    #define bug(x)  cout<<"bug"<<x<<endl;
    
    const int N=1e5+10,M=1e6+10,inf=2147483647;
    const LL INF=1e18+10,mod=998244353;
    
    const int MAXN=1000001;
    int prime[MAXN];//保存素数
    bool vis[MAXN];//初始化
    int Prime(int n)
    {
        int cnt=0;
        memset(vis,0,sizeof(vis));
        for(int i=2; i<n; i++)
        {
            if(!vis[i])
                prime[cnt++]=i;
            for(int j=0; j<cnt&&i*prime[j]<n; j++)
            {
                vis[i*prime[j]]=1;
                if(i%prime[j]==0)
                    break;
            }
        }
        return cnt;
    }
    
    LL num[M],ans[M];
    
    int main()
    {
        int cnt=Prime(1000000);
        int T;
        scanf("%d",&T);
        while(T--)
        {
            for(int i=0; i<1000005; i++)
                num[i]=1,ans[i]=1;
            LL l,r,K;
            scanf("%lld%lld%lld",&l,&r,&K);
            for(int q=0; q<cnt; q++)
            {
                int i=prime[q];
                LL L=(l%i==0?l:(l/i+1)*i);
                for(LL j=L; j<=r; j+=i)
                {
                    LL temp=j,base=1;
                    int x=0;
                    while(temp%i==0)
                    {
                        x++;
                        temp/=i;
                        base*=i;
                    }
                    ans[j-l+1]*=(1LL*K*x+1)%mod;
                    ans[j-l+1]%=mod;
                    num[j-l+1]*=base;
                }
            }
            for(LL i=l; i<=r; i++)
            {
                if(num[i-l+1]!=i)
                    ans[i-l+1]*=K+1,ans[i-l+1]%=mod;
            }
            LL out=0;
            for(LL i=l;i<=r;i++)
                out+=ans[i-l+1],out%=mod;
            printf("%lld
    ",out);
        }
        return 0;
    }
  • 相关阅读:
    容器的注册
    context创建过程解析(三)之deployDirectories
    context创建过程解析(二)之deployWARs
    Redis数据类型
    Kafka常用命令
    使用Charles抓包微信小程序
    DO、DTO、BO、AO、VO、POJO定义
    主题样式之鼠标点击效果
    Mysql常用命令
    Linux常用命令
  • 原文地址:https://www.cnblogs.com/jhz033/p/7280824.html
Copyright © 2011-2022 走看看