首页 > 代码库 > hdu6069 多校Counting Divisors

hdu6069 多校Counting Divisors

  技术分享

   思路:对于n^k其实就是每个因子的个数乘了一个K。然后现在就变成了求每个数的每个质因子有多少个,但是比赛的时候只想到sqrt(n)的分解方法,总复杂度爆炸,就一直没过去,然后赛后看官方题解感觉好妙啊!通过类似素数筛法的方式,把L - R的质因子给分解,就可以在O(nlogn)的时间之内把所以的数给筛出来。

 

/*  gyt
       Live up to every day            */

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<cstring>
#include<queue>
#include<set>
#include<string>
#include<map>
#include <time.h>
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 1e6+10;
const ll maxm = 1e7;
const ll mod = 998244353;
const int INF = 0x3f3f3f;
const ll inf = 1e15 + 5;
const db eps = 1e-9;
int is[maxn], pri[maxn];
ll f[maxn], num[maxn];
int cnt;
ll r, l, k;

void prim() {
    cnt=0;
    memset(is, 0, sizeof(is));
    memset(pri, 0, sizeof(pri));
    for (int i=2; i<maxn; i++) {
        if (!is[i]) {
            pri[++cnt]=i;
            for (int j=i+i; j<maxn; j+=i) {
                is[j]=1;
            }
        }
    }
}
void solve() {
    scanf("%lld%lld%lld", &l, &r, &k);
    for (ll i=l; i<=r; i++) {
        f[i-l+1]=1, num[i-l+1]=i;
    }
    for (int i=1; i<=cnt; i++) {
        ll be=l+pri[i]-l%pri[i];
        if (l%pri[i]==0)  be=l;
        for (ll j=be; j<=r; j+=pri[i]) {
            ll sum=0;
            while (num[j-l+1]%pri[i]==0) {
                sum++;
                num[j-l+1]/=pri[i];
            }
            f[j-l+1]=f[j-l+1]*(k*sum%mod+1)%mod;
        }
    }
    ll ans=0;
    for (ll i=l; i<=r; i++) {
        if (num[i-l+1]!=1)  f[i-l+1]=f[i-l+1]*(k+1)%mod;
        ans=(ans+f[i-l+1])%mod;
    }
    cout<<ans<<endl;
}
int main() {
    int t = 1;
    //freopen("in.txt", "r", stdin);
    scanf("%d", &t);
    prim();
    while(t--)
        solve();
    return 0;
}

  解释:

for (ll i=l; i<=r; i++) {
        f[i-l+1]=1, num[i-l+1]=i;
}

  如果不进行这一步,那么数是1~1^12存不下,但是我们已知r-l<=1e6,这样就可以存下了。

  f[i]表示当前的因数个数,num[i],从l到r(下标1-(r-l+1))的数。

for (ll i=l; i<=r; i++) {
        if (num[i-l+1]!=1)  f[i-l+1]=f[i-l+1]*(k+1)%mod;
        ans=(ans+f[i-l+1])%mod;
}

  判断当前这个数还有没有素数因子。

 

hdu6069 多校Counting Divisors