题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6069
题意:求[l,r]范围内i^k的因子个数和。
分析:先根据唯一分解定理把当前数分解成素数乘积的形式
素因子分解:n = p1 ^ e1 * p2 ^ e2 *..........*pn ^ en
则n的因子个数为(e1+1)*(e2+1)*.........*(en+1)
n^k的因子的个数为:(e1*k+1)*(e2*k+1)*.........*(en*k+1)
所以我们可以筛出[l,r]范围内[1,1e6]素因子的个数,然后判断是否为1再做相应处理。如果不为1,则必有大于1e6的素数。突破口是区间的限制。
反思:做比赛时想到筛素数去处理,中间的关系也找到了,但不知道怎么去处理大于1e6的素数,也没想过去存中间的结果,还是思考的不够,思维方式的问题。。。
CODE:
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<math.h>
#define INF 0x3f3f3f3f
#define lson l,m,root<<1
#define rson m+1,r,root<<1|1
typedef long long LL;
using namespace std;
const int maxn=1000005;
const int mod=998244353;
LL l,r,k;
LL prime[maxn];
void getprime()
{
memset(prime,0,sizeof(prime));
for(int i=2; i<=maxn; i++)
{
if(!prime[i])
prime[++prime[0]]=i;
for(int j=1; j<=prime[0]&&prime[j]<maxn/i; j++)
{
prime[prime[j]*i]=1;
if(i%prime[j]==0)
break;
}
}
}
LL cnt[maxn],q[maxn];
int main()
{
int t;
scanf("%d",&t);
getprime();
while(t--)
{
scanf("%lld%lld%lld",&l,&r,&k);
LL sum=0;
for(int i=0; i<=r-l; i++)
cnt[i]=1,q[i]=l+i;//把[l,r]的数存在[0,r-l]内
for(int i=1; i<=prime[0]&&prime[i]<=r; i++)
{
LL j=l/prime[i]+(l%prime[i]!=0);//注意
for(j=j*prime[i]; j<=r; j+=prime[i])
{
LL count=0;
while(q[j-l]%prime[i]==0)
q[j-l]/=prime[i],count++;
cnt[j-l]*=(count*k+1)%mod;
cnt[j-l]%=mod;
}
}
for(int i=0; i<=r-l; i++)
{
if(q[i]!=1)
sum+=((k+1)*cnt[i])%mod;//[l,r]范围内有大于1e6的素数
else
sum+=cnt[i];
sum%=mod;
// cout<<cnt[i]<<" ";
}
printf("%lld\n",sum);
}
return 0;
}
Counting Divisors
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 1319 Accepted Submission(s): 469
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 :
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) .
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