2017 Multi-University Training Contest - Team 4 3.Counting Divisors(数论)

链接: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\n",res);
77     }
78     return 0;
79 }

 

posted @ 2017-08-03 22:43  7391_KID  阅读(166)  评论(0编辑  收藏  举报