zoukankan      html  css  js  c++  java
  • 2017 Multi-University Training Contest

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6069

    题目:

    Counting Divisors

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
    Total Submission(s): 1235    Accepted Submission(s): 433


    Problem Description
    In mathematics, the function d(n) denotes the number of divisors of positive integer n.

    For example, d(12)=6 because 1,2,3,4,6,12 are all 12's divisors.

    In this problem, given l,r and k, your task is to calculate the following thing :

    (i=lrd(ik))mod998244353

     
    Input
    The first line of the input contains an integer T(1T15), denoting the number of test cases.

    In each test case, there are 3 integers l,r,k(1lr1012,rl106,1k107).
     
    Output
    For each test case, print a single line containing an integer, denoting the answer.
     
    Sample Input
    3 1 5 1 1 10 2 1 100 3
     
    Sample Output
    10 48 2302
     
    Source
     

     思路:

      首先需要知道:一个数可以用唯一分解定理表示成:n=p1^a1*p2^2......*pn^an

             质约数个数为(a1+1)*(a2+1)*....*(an+1)

      那么n^k的质约数个数为(a1*k+1)*(a2*k+1)*.....*(an*k+1)

      所以这题的关键是求l,r区间每个数的质约数有那些,且次数是多少。

      考虑到:l,r最大为1e12,所以枚举1-1e6内的所有素数后即可知道l,r中每个数的质约数有哪些,同时可以知道次数是多少

      但是直接在1-1e6的素数表内查找l,r中的某个数的素约数的时间复杂度是O(1e6),显然不可行。

      所以可以通过线性筛的思想来求:对于1-1e6的素数,考虑他会在l,r内筛掉哪些数即可。

      因为1e12每个数最多有20左右的质约数,所以时间复杂度是O((r-l)*20)+O(1e5)(质数表大小)

      

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define MP make_pair
     6 #define PB push_back
     7 typedef long long LL;
     8 typedef pair<int,int> PII;
     9 const double eps=1e-8;
    10 const double pi=acos(-1.0);
    11 const int K=1e6+7;
    12 const int mod=998244353;
    13 
    14 LL ql,qr,qk,cnt,ls[K],sum[K],pr[K];
    15 bool pa[K];
    16 void init(void)
    17 {
    18     for(int i=2;i<=1000000;i++)
    19     if(!pa[i])
    20     {
    21         pr[cnt++]=i;
    22         for(int j=i*2;j<=1000000;j+=i) pa[j]=1;
    23     }
    24 }
    25 LL sc(int t)
    26 {
    27     LL ans=0;
    28     for(LL i=ql;i<=qr;i++) sum[i-ql]=1,ls[i-ql]=i;
    29     for(int i=0;i<cnt;i++)
    30     {
    31         for(LL j=max(2LL,(ql+pr[i]-1)/pr[i])*pr[i];j<=qr;j+=pr[i])
    32         {
    33             LL cnt=0;
    34             while(ls[j-ql]%pr[i]==0) ls[j-ql]/=pr[i],cnt++;
    35             sum[j-ql]=(sum[j-ql]*(qk*cnt+1))%mod;
    36         }
    37     }
    38     for(LL i=ql;i<=qr;i++)
    39     {
    40         if(ls[i-ql]!=1) sum[i-ql]=(sum[i-ql]*(qk+1))%mod;
    41         ans+=sum[i-ql];
    42         if(ans>=mod) ans-=mod;
    43     }
    44     return ans;
    45 }
    46 
    47 int main(void)
    48 {
    49     //freopen("in.acm","r",stdin);
    50     int t;scanf("%d",&t);
    51     init();
    52     while(t--)
    53     {
    54         scanf("%lld%lld%lld",&ql,&qr,&qk);
    55         printf("%lld
    ",sc(t));
    56     }
    57     return 0;
    58 }
  • 相关阅读:
    在多线程中使用静态方法是否有线程安全问题(转载)
    为什么乐观的人多能成功呢?
    每个人都是超级英雄-《技巧:如何用一年的时间获得十年的经验》
    003|再谈10000小时,三板斧破四困境
    002|也谈10000小时
    在职场中如何通过讲故事,影响他人、支持自己(下篇)
    全面解读:微信服务号升级和群发增至4条的应用方法
    Technical reading July-15
    read links July-14
    Technical news July-11
  • 原文地址:https://www.cnblogs.com/weeping/p/7282900.html
Copyright © 2011-2022 走看看