hdu 6069 區間素數+思維
阿新 • • 發佈:2019-02-11
Counting DivisorsTime 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. 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。要你求取模
做法:
如果沒有k次這個條件,可以聯想到母函式。如果,那麼,因為每個因子都可以選擇不取,也可以選擇取多少,相乘就是要求的因子數量了。如果碰到質數,那麼就是a1就是1。
但是本題中對每個數又加了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;
}