• 2017 Multi-University Training Contest


    链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1003&cid=762

    题意:记d(n)为n的因子个数,给定l,r,k,求∑d(i^k),(i=l,l+1,...,r)。

    分析:记n=(p1^a1)*(p2^a2)*...*(pt^at),显然d(n^k)=∏(k*ai+1),(i=1,2,...,t),而且d(n)是个积性函数,可以想到用线性筛搞一下,然而数据范围10^12。。先筛10^6以内的质数p,然后枚举p在[l,r]以内的倍数,把倍数除尽p,假设除了m次,就乘一个k*m+1,如果最后有的数没有被除成1,就再乘一个k+1,再把所有结果加起来就是答案了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 typedef long long ll;
     6 const int mod=998244353;
     7 int pri[100000],len=0,ans[1000005];
     8 ll m[1000005],l,r;
     9 int k,res;
    10 void CalPri(){
    11     int maxp=1000005;
    12     bool Is_pri[maxp];
    13     memset(Is_pri,-1,sizeof(Is_pri));
    14     for(int i=2;i<maxp;i++){
    15         if(Is_pri[i]){
    16             pri[len++]=i;
    17 //            d[i]=k+1;
    18         }
    19         for(int j=0;j<len&&(ll)i*pri[j]<maxp;j++){
    20             Is_pri[i*pri[j]]=false;
    21             if(i%pri[j]==0){
    22 //                int q=i,c=1;
    23 //                while(q%pri[j]==0){c++;q/=pri[j];}
    24 //                d[i*pri[j]]=((ll)d[q]*(k*c+1))%mod;
    25                 break;
    26             }
    27 
    28         }
    29     }
    30 }
    31 void solve(){
    32     for(int i=0;i<=r-l;i++){
    33         ans[i]=1;
    34         m[i]=i+l;
    35     }
    36     for(int i=0;i<len&&pri[i]<=r;i++){
    37         int p=pri[i];
    38         for(ll j=(ll)((l-1)/p+1)*p;j<=r;j+=p){
    39             int c=0;
    40             while(m[j-l]%p==0){c++;m[j-l]/=p;}
    41             ans[j-l]=((ll)ans[j-l]*(k*c+1))%mod;
    42         }
    43     }
    44     res=0;
    45     for(int i=0;i<=r-l;i++){
    46         if(m[i]!=1)
    47             ans[i]=((ll)ans[i]*(k+1))%mod;
    48         res=(res+ans[i])%mod;
    49     }
    50 }
    51 int test(){
    52     int a=0;
    53     for(ll i=l;i<=r;i++){
    54         ll n=i,q=1;
    55         for(int j=0;j<len;j++){
    56             int p=pri[j],c=0;
    57             while(n%p==0){
    58                 n/=p;c++;
    59             }
    60             q=(q*(c*k+1))%mod;
    61         }
    62         if(n!=1)q=(q*(k+1))%mod;
    63         a=(a+q)%mod;
    64     }
    65     return a;
    66 }
    67 int main(){
    68     //freopen("e:\in.txt","r",stdin);
    69     CalPri();
    70     int t;
    71     scanf("%d",&t);
    72     while(t--){
    73         int ans=0;
    74         cin>>l>>r>>k;
    75         solve();
    76         printf("%d
    ",res);
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    从0到1构建适配不同端(微信小程序、H5、React-Native 等)的taro + dva应用
    一个基于Ionic3.x cordova的移动APP demo
    基于 MUI 构建一个具有 90 +页面的APP应用
    风清杨之Oracle的安装与说明
    浅析C#中的“==”和Equals
    window.open()的使用
    动态生成级联下拉框和多选框
    生成二维码的两种方式
    登录添加验证码校验
    oracle11g的安装以及配置
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7282503.html
Copyright © 2020-2023  润新知