hdu6069(大区间素数)
2018-04-03 19:35
225 查看
Counting Divisors
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 3713 Accepted Submission(s): 1366
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<
e2cd
/span>
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
题意: 给出 l, r, k.求:(lambda d(i^k))mod998244353,其中 l <= i <= r, d(i) 为 i 的因子个数.
思路:若 x 分解成质因子乘积的形式为 x = p1^a1 * p2^a2 * ... * pn^an,那么 d(x) = (a1 + 1) * (a2 + 1) * ... * (an + 1) .显然 d(x^k) = (a1 * k + 1) * (a2 * k + 1) * ... * (an * k + 1) .
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
const int maxn=1000100;
const ll mod=998244353;
ll prime[maxn]; //第i个素数
bool is_prime[maxn]; //is_prime[i]为true表示i是素数
ll sum[maxn]; //代表每个数的k次的因子个数
ll a[maxn];
//返回n以内的素数的个数
int sieve(int n)
{
int p = 0;
memset(is_prime,true,sizeof(is_prime));
is_prime[0] = is_prime[1] = false;
for (int i = 2; i <= n; i++){
if (is_prime[i]){
prime[p++] = i;
for (int j = 2 * i; j <= n; j += i)
is_prime[j] = false;
}
}
return p;
}
int main()
{
int p1=sieve(maxn-1);
int t;
ll l,r,k;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld%lld",&l,&r,&k);
for(int i=0;i<=r-l;i++)
{
sum[i]=1;
a[i]=i+l;
}
for(int i=0;prime[i]*prime[i]<=r;i++)
{
ll x=(l/prime[i]+(l%prime[i]?1:0))*prime[i];
for(ll p=x;p<=r;p+=prime[i])
{
ll tmp=0;
while(a[p-l]%prime[i]==0)
{
tmp++;
a[p-l]/=prime[i];
}
sum[p-l]=(sum[p-l]*(tmp*k+1)%mod)%mod;
}
}
ll ans=0;
for(int i=0;i<=r-l;i++)
{
//其含有的质因子中有大于1e6的质数,需要加入计算
if(a[i]!=1)sum[i]=(sum[i]*(k+1))%mod;
ans=(ans+sum[i])%mod;
}
printf("%lld\n",ans);
}
}
相关文章推荐
- hdu6069 Counting Divisors 晒区间素数
- HDU6069 Counting Divisors(区间素数筛)
- POJ 2689 Prime Distance(素数区间筛法--经典题)
- poj 2689 l-r区间素数对
- POJ 2689(区间素数筛)
- [SMOJ1771]区间素数
- POJ2689——Prime Distance(大区间素数筛)
- LightOJ 1197 - Help Hanzo 【思维找素数 -> 区间素数筛选】
- 【在线等急急急!】相差为2的两个素数称为孪生素数。例如,3与5,41与43等都是孪生素数。设计程序求出指定区间上的所有孪生素数对。区间上限和下限由键盘获取。
- [tips]筛选特定区间内素数个数
- ZOJ - 3911 (区间替换,单点更新,区间和查询+筛素数)
- 【c++】用c++编写的求任意区间的素数的小程序
- lightoj1197区间素数筛
- POJ2689-Prime Distance-区间筛素数
- poj 2689 l-r区间素数对
- POJ题目2689 Prime Distance(任何区间素数筛选)
- 线性求区间欧拉函数(顺便线性求区间内所有素数)(类似欧拉线性素数筛)
- ZJNU - 1433 [a,b]区间素数的个数
- 统计某区间内的素数并打印显示
- T1411 区间内的真素数(#Ⅰ- 6 - 1)