hdu 6069 区间筛

来源:互联网 发布:fedora17 yum无法使用 编辑:程序博客网 时间:2024/06/11 07:04

题意:求出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;}
原创粉丝点击