您的位置:首页 > 其它

hdu 6069 区间筛

2017-08-03 18:43 330 查看
题意:求出i满足l到r区间所有 i^k次方的因子的数量的和。

思路:对10^6的区间进行素数筛, 求出其质因数,再根据每个质因数的(1+number*k)的乘积求出因子和。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN = 1e6+1e3;
bool vis[MAXN];
typedef long long LL;
const int mod = 998244353;
LL num[MAXN];
LL prime[MAXN];
LL a[MAXN];
int cnt;
void seg_vis(LL l,LL r, int k)   //区间筛法
{
LL n=r-l;
for(LL i=0; i<=n; i++) num[i]=1, a[i]=l+i;
for (LL i=0; prime[i]<=n+1&&i<cnt; i++)
{
LL j = 0;
if (l % prime[i] != 0)//第一个需要筛掉的数(j+a) % isprime[i] == 0
j = prime[i] - l % prime[i];
for (; j<=n; j+=prime[i])
{
LL Count = 0;
while(a[j]%prime[i]==0)
{
Count++;
a[j]/=prime[i];
}
num[j]=(num[j]*(k*Count+1))%mod;
}
}
LL sum=0;
for(LL i=0; i<=n; ++i)
{
if(a[i]!=1)
num[i]=num[i]*(k+1)%mod;
sum=(sum+num[i])%mod;
}
printf("%lld\n", sum);
return ;
}
int main()
{
cnt=0;
memset(vis, true, sizeof(vis));
for(int i=2; i<MAXN; i++) //预处理
if(vis[i])
{
prime[cnt++]=i;
for(int j=2*i; j<MAXN; j+=i)
vis[j]=false;
}
LL l, r;
int t;
int k;
scanf("%d", &t);
while(t--)
{
scanf("%lld %lld %d", &l, &r, &k);
seg_vis(l, r, k);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: