杭电 6069 多校 Counting Divisors

来源:互联网 发布:贝多芬梅毒 知乎 编辑:IT博客网 时间:2020/02/23 11:51

Counting Divisors

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

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

首先r-l<= 1e6
之后就是枚举所有l到r 的质数约数
枚举到sqrt(r) ;
long long j=su[i]*(r/su[i]);

这一步直接找到第一个 对当前枚举的素数 l 到 r 中可以除尽的第一个位置
如果小于l 的话 再加上 当前的素数值。

枚举每个素数 对每个位置进行一次性质因数分解。

如 8 就把 8 的2 全部消除 剩下 1
如 6 就把6中的2 消除掉 剩下3.

最后对于每个位置上剩下的值 如果大于sqrt(r) 的话。
那么表示当前位置还有一个素数 在 乘上(k+1)
随后 把区间内所有的和加起来

官方题解 1003
http://bestcoder.hdu.edu.cn/blog/2017-multi-university-training-contest-4-solutions-by-%E9%99%88%E6%9D%BE%E6%9D%A8/

#include <stdio.h>#include <string.h>#include <algorithm>#include <bits/stdc++.h>using namespace std;long long d[10000005];long long su[1000005];const long long mod=998244353;long long tag[1000005];long long sux(long long x){    if(x==2) return 1;    if(x%2==0) return 0;    for(long long i=3;i*i<=x;i+=2)        if(x%i==0) return 0;    return 1;}int main(){    long long sul=0;    for(long long i=2;i<=1000000;i++)    {        if(sux(i))        {            su[sul]=i;            sul++;            //cout<<i<<endl;        }    }    long long t;    cin>>t;    while(t--)    {        long long r,l,k;        cin>>r>>l>>k;        long long ce=sqrt(l);        //cout<<ce<<endl;        for(long long i=0;i<=l-r;i++)        {            tag[i]=i+r;            d[i]=1;        }        ////for(int e=0;e<10;e++) cout<<su[e]<<' ';       // cout<<endl;        for(long long  i=0;i<sul&&su[i]<=l;i++)        {            long long j=su[i]*(r/su[i]);            if(j<r) j+=su[i];            //cout<<"xs "<<j<<' '<<su[i]<<' '<<i<<' '<<su[2]<<' '<<ce<<endl;            long long sum=0;            for(;j<=l;j+=su[i])            {                long long y=j-r;                sum=0;                while(tag[y]%su[i]==0)                {                    tag[y]/=su[i];                    sum++;                    //cout<<"x"<<endl;                }                d[j-r]=d[j-r]*(sum*k+1)%mod;               // cout<<j<<' '<<' '<<su[i]<<endl;            }        }        long long ans=0;        for(long long i=0;i<=l-r;i++)        {            if(tag[i]>ce) d[i]=d[i]*(k+1)%mod;            ans=(ans+d[i])%mod;           // cout<<' '<<tag[i]<<' '<<ce<<' '<<d[i]<<' '<<endl;        }        cout<<ans<<endl;    }}