HDU 6069 Counting Divisors

来源:互联网 发布:unity3d ios 红色问号 编辑:程序博客网 时间:2024/05/29 19:22

题目地址
题意:那个函数是求该数的因子个数,让你求出l~r这个区间中所有数的k次方的d()的和
思路:有一个公式是若i=p1^a1×p2^a2×p3^a3*…pk^ak,则i^K=p1^(a1*K)×p2^(a2*K)×p3^(a3*K)…*pk^(ak*K),i^K的约数的个数就是(a1*K+1)(a2*K+1)(a3*K+1)…(ak*K+1),所以做两次筛选,第一次筛选出10^6的素数,第二次筛选出l~r之间的素数的倍数,其他的可以看代码注释

#include <iostream>#include <cstring>#include <string>#include <queue>#include <vector>#include <map>#include <set>#include <stack>#include <cmath>#include <cstdio>#include <algorithm>#include <iomanip>#define N 1000010#define LL __int64#define inf 0x3f3f3f3f#define lson l,mid,ans<<1#define rson mid+1,r,ans<<1|1#define getMid (l+r)>>1#define movel ans<<1#define mover ans<<1|1using namespace std;const LL mod = 998244353;const double eps = 1e-9;int num;LL ans, cnt[N], q[N], primes[N];bool dp[N];void init() {    memset(dp, false, sizeof(dp));    num = 0;    for (int i = 2; i < N; i++) {        if (!dp[i]) {            primes[num++] = i;            for (int j = i + i; j < N; j += i) {                dp[j] = 1;            }        }    }}int main() {    //cin.sync_with_stdio(false);    int T;    LL l, r, k;    //cin >> T;    scanf("%d", &T);    init();    while (T--) {        scanf("%lld %lld %lld", &l, &r, &k);        //cin >> l >> r >> k;        ans = 0;        if (l == 1) {//1是个特殊情况            ans++, l++;        }        for (LL i = 0; i <= r - l; i++) {            cnt[i] = 1;//初始化所有数假设都是素数            q[i] = i + l;        }        for (LL i = 0; i < num&&primes[i] * primes[i] <= r; i++) {//遍历每一个素数            LL j = l / primes[i] + (l%primes[i] != 0);//当前素数乘以最小的倍数得到比l大的数            for (j = j*primes[i]; j <= r; j += primes[i]) {//求当前素数的倍数                LL tmp = 0;                while (q[j - l] % primes[i] == 0) {//                    q[j - l] /= primes[i];                    tmp++;                }                cnt[j - l] *= (tmp*k) % mod + 1;//乘以k次方,算这个数被用过多少次                cnt[j - l] %= mod;            }        }        for (LL i = 0; i <= r - l; i++) {            if (q[i] != 1)ans += ((k + 1)*cnt[i]) % mod;//根据公式            else ans += cnt[i];//如果当前的值为1            ans %= mod;        }        printf("%lld\n", ans);        //cout << ans << endl;    }    return 0;}
原创粉丝点击