HDU 6069 Counting Divisors 思路题(附赠大神代码)
来源:互联网 发布:人工智能阅读语文答案 编辑:程序博客网 时间:2024/06/08 16:49
传送门
Counting Divisors
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1275 Accepted Submission(s): 449
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, givenl,r and k , your task is to calculate the following thing :
(∑i=lrd(ik))mod998244353
For example,
In this problem, given
Input
The first line of the input contains an integer T(1≤T≤15) , denoting the number of test cases.
In each test case, there are3 integers l,r,k(1≤l≤r≤1012,r−l≤106,1≤k≤107) .
In each test case, there are
Output
For each test case, print a single line containing an integer, denoting the answer.
Sample Input
31 5 11 10 21 100 3
Sample Output
10482302
现将 i 分解成质因子,所有的质因子的幂加上一的乘积,就是d(i);那么d(i^k)就是幂先乘k再加一 的乘积。
素数打表(1-1e6),用素数筛法求L到R里的数的素因子有哪些,用数组保存起来,最后处理。
我的AC代码:(下面有大神代码,思路是一样的,效率快了一倍)
#include <iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn=1000100;#define mod 998244353typedef long long ll;int flag[maxn],pi;int prime[maxn];inline int getprime()//素数打表{ pi=0; memset(flag,false,sizeof(flag)); for(int i=2; i<maxn; i++) { if(!flag[i]) prime[pi++]=i; for(int j=0; (j<pi)&&(i*prime[j]<maxn); j++) { flag[i*prime[j]]=true; if(i%prime[j]==0) break; } } return pi;}int cun[1000100][50],ge[1000100];//cun存每个数字的素因子有哪些,ge存每个数字的素因子个数int main(){ int s=getprime(); int t; scanf("%d",&t); while(t--) { ll l,r, kk; scanf("%lld%lld%lld",&l,&r,&kk); memset(ge,0,sizeof(ge)); for(int i=0; i<s; i++)//用i遍历素数,j为倍数,枚举倍数j 符合L到R区间的存下来。 { int d=prime[i]; if((ll)d*d>r) break;//优化,等到只剩一个大素数时,直接break;(比赛时没有想到这个优化,都TLE哭了) ll j=l/d,rr=r; while(j<rr) { ll mid=(j+rr)>>1; if(mid*d>=l) rr=mid; else j=mid+1; } j=rr; for (; j*d<=r; j++) { ll g=d*j-l; cun[g][ge[g]++]=prime[i]; } } ll num=0; for(ll i=l; i<=r; i++) { ll x=i; ll gg=i-l; ll ans=1; for(int j=0; j<ge[i-l]; j++) { ll sum=0; while(x%cun[gg][j]==0) { sum++; x/=cun[gg][j]; } ans=ans*(sum*kk+1); if(ans>=mod) ans%=mod; } if(x>1) ans=ans*(kk+1); if(ans>=mod) ans%=mod; num+=ans; } num%=mod; printf("%lld\n",num); } return 0;}
大神代码:
#include<cstdio>typedef long long ll;const int N=1000010,P=998244353;int Case,i,j,k,p[N/10],tot,g[N],ans;ll n,l,r,f[N];bool v[N];inline void work(ll p){ for(ll i=l/p*p; i<=r; i+=p)if(i>=l) { int o=0; while(f[i-l]%p==0)f[i-l]/=p,o++; g[i-l]=1LL*g[i-l]*(o*k+1)%P; }}int main(){ for(i=2; i<N; i++) { if(!v[i])p[tot++]=i; for(j=0; j<tot&&i*p[j]<N; j++) { v[i*p[j]]=1; if(i%p[j]==0)break; } }// 素数筛法 scanf("%d",&Case); while(Case--) { scanf("%lld%lld%d",&l,&r,&k); n=r-l; for(i=0; i<=n; i++)f[i]=i+l,g[i]=1; for(i=0; i<tot; i++) { if(1LL*p[i]*p[i]>r)break; work(p[i]); } for(ans=i=0; i<=n; i++) { if(f[i]>1)g[i]=1LL*g[i]*(k+1)%P; ans=(ans+g[i])%P; } printf("%d\n",ans); } return 0;}
阅读全文
0 0
- HDU 6069 Counting Divisors 思路题(附赠大神代码)
- hdu 6069 Counting Divisors
- [HDU]6069 Counting Divisors
- HDU 6069 Counting Divisors
- HDU 6069 Counting Divisors
- HDU-6069 Counting Divisors
- HDU 6069 Counting Divisors
- HDU-6069 Counting Divisors
- HDU 6069 Counting Divisors
- HDU 6069 Counting Divisors
- hdu 6069 Counting Divisors
- HDU 6069 Counting Divisors
- hdu--6069--Counting Divisors
- HDU-6069 Counting Divisors
- HDU-6069 Counting Divisors
- HDU 6069 Counting Divisors
- hdu 6069 Counting Divisors (素数)
- HDU 6069 Counting Divisors(求因子)
- HDU 2017 多校联赛4 1011 Time To Get Up
- Mosca MQTT
- 浅谈 MVP in Android
- recycleView的条目长按换位置
- 昨天的代码
- HDU 6069 Counting Divisors 思路题(附赠大神代码)
- poj-1664 放苹果
- python scrapy之爬取 zhengfu网站
- javascript的日期函数
- Android ViewDragHelper完全解析 自定义ViewGroup神器
- XYNU OJ 1104: 例题6-8 单词统计
- ViewDragHelper实战 自己打造Drawerlayout
- 从零开始搭建环境编写操作系统 AT&T GCC (四)绘制界面
- Reading Note: ThiNet: A Filter Level Pruning Method for Deep Neural Network Compression