1. 程式人生 > >hdu 6069 區間素數+思維

hdu 6069 區間素數+思維

Counting Divisors

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


 

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

題意:

       函式d(x)表示x的所有因子的數量(包括1和自己),現在給你l,r,k。要你求(\sum _{i=l}^{r}d(i^{k}))取模 

做法:

       如果沒有k次這個條件,可以聯想到母函式。如果x=p_{1}^{a_{1}}p_{2}^{a_{2}}p_{3}^{a_{3}}....p_{n}^{a_{n}},那麼d(x)=(1+a_{1})(1+a_{2})(1+a_{3})...(1+a_{n}),因為每個因子都可以選擇不取,也可以選擇取多少,相乘就是要求的因子數量了。如果碰到質數,那麼就是a1就是1。

       但是本題中對每個數又加了k次,相當於把x=p_{1}^{a_{1}}p_{2}^{a_{2}}p_{3}^{a_{3}}....p_{n}^{a_{n}}

變成了x^{k}=p_{1}^{a_{1}*k}p_{2}^{a_{2}*k}p_{3}^{a_{3}*k}....p_{n}^{a_{n}*k},只要把你算到的a_{i}乘上k就好了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
const int mod=998244353;
const int maxn=1000005;
ll prime[maxn],numprime;
bool vis[maxn];
ll ans[maxn],val[maxn];
void init(){
    for(int i=2;i<maxn;i++){
        if(!vis[i])prime[++numprime]=i;
        for(int j=1;j<=numprime&& prime[j]*i<maxn;j++){
            vis[prime[j]*i]=1;
            if(i%prime[j]==0)break;
        }
    }
}
void solve(ll l,ll r,ll k){
    for(ll i=l;i<=r;i++){
        ans[i-l]=1;  val[i-l]=i;
    }
    for(ll i=1;i<=numprime&&prime[i]<=r;i++){
        ll now=prime[i],fir=(l/prime[i]+(l%prime[i]?1:0))*prime[i];
        for(ll j=fir;j<=r;j+=now){
            ll cnt=0;
            while(val[j-l]%now==0){
                cnt++;  val[j-l]/=now;
            }
            ans[j-l]=((1+cnt*k)%mod*ans[j-l])%mod;
        }
    }
    ll sum=0;
    for(ll i=l;i<=r;i++){
        if(val[i-l]!=1)  ans[i-l]=(1+k)*ans[i-l]%mod;
        sum=(sum+ans[i-l])%mod;
    }
    printf("%lld\n",sum);
}
int main(){
    init();
    int t;
    cin>>t;
    while(t--){
        ll l,r,k;
        scanf("%lld%lld%lld",&l,&r,&k);
        solve(l,r,k);
    }
    return 0;
}