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 }
  • 相关阅读:
    547. Friend Circles
    399. Evaluate Division
    684. Redundant Connection
    327. Count of Range Sum
    LeetCode 130 被围绕的区域
    LeetCode 696 计数二进制子串
    LeetCode 116 填充每个节点的下一个右侧节点
    LeetCode 101 对称二叉树
    LeetCode 111 二叉树最小深度
    LeetCode 59 螺旋矩阵II
  • 原文地址:https://www.cnblogs.com/weeping/p/7282900.html
Copyright © 2011-2022 走看看