zoukankan      html  css  js  c++  java
  • 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;
    }

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

  • 相关阅读:
    socketpair和pipe的区别
    C++异常与析构函数及构造函数
    System v shm的key
    不可靠信号SIGCHLD丢失的问题
    非阻塞IO函数
    Android 编译时出现r cannot be resolved to a variable
    找工作笔试面试那些事儿(5)---构造函数、析构函数和赋值函数
    unable to load default svn client 和 Eclipse SVN 插件与TortoiseSVN对应关系
    演示百度地图操作功能
    求第i个小的元素 时间复杂度O(n)
  • 原文地址:https://www.cnblogs.com/gggyt/p/7291262.html
Copyright © 2011-2022 走看看