Counting Divisors HDU - 6069
Posted yijiull
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Counting Divisors HDU - 6069相关的知识,希望对你有一定的参考价值。
Counting Divisors
题意:给定区间[a,b]和k,求xk有多少因子(x属于[a,b]),求和。
a、b最大可达到1e12,但是b-a<1e6。
一开始愚蠢的一个一个分解然后去求有多少因子然后求和,范围那么大裸裸的超时啊!
可以枚举素数,对每一个素数,把区间内所有可以分解的进行分解。
最后再求和。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn=1e6+10; 5 const int mod=998244353; 6 int vis[maxn]; 7 int pri[maxn]; 8 ll ans[maxn],num[maxn]; 9 int cnt=0; 10 void init(){ 11 cnt=0; 12 memset(vis,0,sizeof(vis)); 13 for(ll i=2;i<maxn;i++){ 14 if(!vis[i]){ 15 pri[cnt++]=i; 16 for(ll j=i*i;j<maxn;j+=i) 17 vis[j]=1; 18 } 19 } 20 } 21 22 int main(){ 23 init(); 24 int t; 25 scanf("%d",&t); 26 while(t--){ 27 ll a,b,k; 28 scanf("%lld%lld%lld",&a,&b,&k); 29 int r=b-a+1; 30 for(int i=0;i<r;i++){ 31 num[i]=i+a; 32 ans[i]=1; 33 } 34 for(int i=0;i<cnt;i++){ 35 int x=pri[i]; 36 ll s=(x-a%x)%x; //!! 37 for(;s<r;s+=x){ 38 int temp=0; 39 while(num[s]%x==0){ 40 temp++; 41 num[s]/=x; 42 } 43 ans[s]*=(k*temp+1); 44 if(ans[s]>=mod) ans[s]%=mod; 45 } 46 } 47 ll res=0; 48 for(int i=0;i<r;i++){ 49 if(num[i]>1) ans[i]=ans[i]*(k+1)%mod; 50 res+=ans[i]; 51 if(res>=mod) res-=mod; 52 } 53 54 printf("%d\n",res); 55 } 56 }
以上是关于Counting Divisors HDU - 6069的主要内容,如果未能解决你的问题,请参考以下文章
第四场 hdu 6069 Counting Divisors (逆向思维)
hdu 6069 Counting Divisors(求因子的个数)