hdu 6069 Counting Divisors(求因子的个数)

Counting Divisors

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 3170    Accepted Submission(s): 1184

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(1≤T≤15), denoting the number of test cases.

In each test case, there are 3 integers l,r,k(1≤l≤r≤1012,r?l≤106,1≤k≤107).

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

2017 Multi-University Training Contest - Team 4

Recommend

liuyiding   |   We have carefully selected several similar problems for you:  6119 6118 6117 6116 6115

题目大意:

求   l<= t <=r,  求   对多有满足条件的t 的   d(t^k)=t^k的所有因子的个数    的总和

题解:

根据约数个数定理:n=p1^a1×p2^a2×p3^a3*…*pk^ak,n的约数的个数就是(a1+1)(a2+1)(a3+1)…(ak+1).

只要求1~1e6之间的素数,如果当某个数除完前面的素数的时候还!=1,那么那个数字就是>1e6的素数。

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<cmath>
#include<cstring>
#include<bits/stdc++.h>

using namespace std;
const long long mod=998244353;
long long ans,l,r,k,len;
int T;
long long f[100000],num[1000005],a[1000005];
void pre()
{
    bool flag;
    len=0;
    f[++len]=2;
    for(int i=3;i<=1e6;i++)
    {
        flag=1;
        for(int j=2;j<=sqrt(i);j++)
        if (i%j==0) {flag=0; break;}
        if (flag) f[++len]=i;
    }
    return;
}

int main()
{
    pre(); //预处理出1~1e6之间的素数
    scanf("%d",&T);
    for(;T>0;T--)
    {
        scanf("%lld%lld%lld",&l,&r,&k);
        for(int i=0;i<=r-l;i++) {num[i]=1; a[i]=i+l;}  //num【i】表示 i 这个数的因子个数
        ans=0;
        for(int i=1;i<=len;i++)
        {
            long long s=(l/f[i])*f[i];
            if (s<l) s+=f[i];
            for(long long j=s;j<=r;j+=f[i])
            {
                long long w=0;
                while(a[j-l]%f[i]==0)
                {
                    a[j-l]/=f[i];
                    w++;
                }
                num[j-l]=num[j-l]*(w*k+1)%mod;
            }
        }
        for(int i=0;i<=r-l;i++)
            if (a[i]>1) num[i]=num[i]*(k+1)%mod;  //特殊判断还剩下的数字!=1的情况,也就是还有一个大素数

        for(int i=0;i<=r-l;i++) ans=(ans+num[i])%mod;
        printf("%lld\n",ans);
    }
    return 0;
}
时间: 2024-10-29 03:51:43

hdu 6069 Counting Divisors(求因子的个数)的相关文章

HDU 6069 Counting Divisors —— 2017 Multi-University Training 4

Counting Divisors Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 2599    Accepted Submission(s): 959 Problem Description In mathematics, the function d(n) denotes the number of divisors of p

HDU 6069 Counting Divisors(区间素数筛法)

题意:...就题面一句话 思路:比赛一看公式,就想到要用到约数个数定理 约数个数定理就是: 对于一个大于1正整数n可以分解质因数: 则n的正约数的个数就是 对于n^k其实就是每个因子的个数乘了一个K 然后现在就变成了求每个数的每个质因子有多少个,但是比赛的时候只想到sqrt(n)的分解方法,总复杂度爆炸,就一直没过去,然后赛后看官方题解感觉好妙啊! 通过类似素数筛法的方式,把L - R的质因子给分解,就可以在O(nlogn)的时间之内把所以的数给筛出来. 代码: /** @xigua */ #i

第四场 hdu 6069 Counting Divisors (逆向思维)

http://acm.hdu.edu.cn/showproblem.php?pid=6069 题目大意:求 i 从 l 到 r 中 i 的k次方的因子数之和. 解题思路:我们可以知道一个数有因子,则这个数的因子一定是若干个质数因子排列组合得到的.我们首先要得到10^6中的素数,然后它的因子数量是 相同质因子数量+1 的乘积,所以我们能够想到从 l 到 r 枚举每一个i得到其 相同质因子数量+1 的乘积 的累加和.但是这样在枚举时会发现有一些质数是并不是所求的 i 的因子,所以我们应该反过来考虑,

HDU 6069 Counting Divisors(唯一分解定理+因子数)

http://acm.hdu.edu.cn/showproblem.php?pid=6069 题意: 思路: 根据唯一分解定理,$n={a_{1}}^{p1}*{a2_{}}^{p2}...*{a_{m}}^{pm}$,那么n的因子数就是 n的k次方也是一样的,也就是p前面乘个k就可以了. 先打个1e6范围的素数表,然后枚举每个素数,在[ l , r ]寻找该素数的倍数,将其分解质因数. 到最后如果一个数没有变成1,那就说明这个数是大于1e6的质数.(它就只有0和1两种选择) 1 #includ

hdu 6069 Counting Divisors

题意:给出求L,R 之间的数的K次方的因子数之和 思路:打表求出1~10^6之间的素数,枚举[L,R]之间素数的倍数,然后按算数基本定理求出因子个数和.处理过后[L,R]之间的数要么是1,要么是一个素数,再次根据算数基本定理计算因子个数和. #include<bits/stdc++.h> #define MAXSIZE 1000015 #define INF 0x3f3f3f3f #define LL long long #define MOD 998244353 using namespac

Poj2992Divisors 组合数求因子的个数

Divisors Description Your task in this problem is to determine the number of divisors of Cnk. Just for fun -- or do you need any special reason for such a useful computation? Input The input consists of several instances. Each instance consists of a

POJ2992:Divisors(求N!因子的个数,乘性函数,分解n!的质因子)

题目链接:http://poj.org/problem?id=2992 题目要求:Your task in this problem is to determine the number of divisors of Cnk. Just for fun -- or do you need any special reason for such a useful computation? 题目解析:这题也是TLE了无数遍,首先说一下求因子数目的函数是积性函数,积性函数即f(n)=f(a)*f(b)

POJ 2992-Divisors(求组合数质因子的个数)

Divisors Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2992 Appoint description:  System Crawler  (2015-04-24) Description Your task in this problem is to determine the number of divisors of C

Counting Divisors HDU - 6069

Counting Divisors HDU - 6069 题意:给定区间[a,b]和k,求xk有多少因子(x属于[a,b]),求和. 题解:http://blog.csdn.net/zlh_hhhh/article/details/76680641 a.b最大可达到1e12,但是b-a<1e6. 一开始愚蠢的一个一个分解然后去求有多少因子然后求和,范围那么大裸裸的超时啊! 可以枚举素数,对每一个素数,把区间内所有可以分解的进行分解. 最后再求和. 1 #include <bits/stdc++