【2017 Multi-University Training Contest - Team 4】Counting Divisors
2017-10-04 18:44
489 查看
【Link】:http://acm.hdu.edu.cn/showproblem.php?pid=6069
【Description】
定义d(i)为数字i的因子个数;
求∑rld(ik)
其中l,r<=1012且r−l<=106
【Solution】
如果把一个数x质因数分解成p1a1∗p2a2∗...∗pnan
的形式;
可知数字x的因子个数为
(a1+1)∗(a2+1)∗...∗(an+1)
因为i还有k次方;
所以答案就是
(a1∗k+1)∗(a2∗k+1)∗...∗(an∗k+1)
需要对l..r里面所有的数字都进行质因数分解;
可以这样
先处理出2..r√之间的所有素数;
然后枚举每个素数i它在l..r之间的倍数x;
则对x 用素数i进行质因数分解,也即一直除它;
这样,就能算出来x在质因数分解的时候,素数i最后的指数是多少了;
(累乘数字x的答案就好);
记录x在进行质因数分解的时候被除剩下的数字,除的时候是用
这个记录的数字除;
最后这个数字可能会不变;
因为它本身可能就是一个素数;
所以小于r√的素数可能不是它的因子;
但是不可能还有大于r√的因子;
所以如果除剩下的数字还大于0;
答案再乘上(k+1)就好;
最后把每个数字它的答案累加起来;
(一开始可以用O(n)的素数筛求出1..n之间的所有素数);
【NumberOf WA】
many times
【Reviw】
一开始一直往O(n14)的质因数分解想了;
没想到这种方法.
判断出某个素数是某个数的因子之后,不要再记录它的因子是什么了;
直接就开始质因数分解,这样比较快;
不然会超时.
【Code】
#include <bits/stdc++.h> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define LL long long #define rep1(i,a,b) for (int i = a;i <= b;i++) #define rep2(i,a,b) for (int i = a;i >= b;i--) #define mp make_pair #define pb push_back #define fi first #define se second #define ms(x,y) memset(x,y,sizeof x) #define ri(x) scanf("%d",&x) #define rl(x) scanf("%lld",&x) #define rs(x) scanf("%s",x+1) #define oi(x) printf("%d",x) #define ol(x) printf("%lld",x) #define Open() freopen("F:\\rush.txt","r",stdin) #define Close() ios::sync_with_stdio(0) typedef pair<int,int> pii; typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1}; const int dy[9] = {0,0,0,-1,1,-1,1,-1,1}; const double pi = acos(-1.0); const int N = 1e6; const LL MOD = 998244353; bool iszs[N+100]; vector <int> zsb; LL num[N+100],ans[N+100]; int main(){ //Open(); //Close(); ms(iszs,true); rep1(i,2,N) { if (iszs[i]) zsb.pb(i); int len = zsb.size(); rep1(j,0,len-1) { int t = zsb[j]; if (i*t>N) break; iszs[i*t] = false; if (i%t==0) break; } } int T; ri(T); while (T--){ LL l,r,k; rl(l),rl(r),rl(k); for (LL i = l;i <= r;i++) num[i-l+1] = i,ans[i-l+1] = 1; rep1(i,0,(int) zsb.size()-1){ LL x = zsb[i]; if (x > r) break; LL temp = ((l-1)/x + 1)*x; for (LL i = temp;i <= r;i+=x){ LL tot = i,cnt = 0; while (tot%x==0){ tot/=x; num[i-l+1]/=x; cnt++; } ans[i-l+1] = ans[i-l+1]*(cnt*k+1)%MOD; } } LL fans = 0; for (LL i = l;i <= r;i++){ if (num[i-l+1]!=1){ fans = (fans + ans[i-l+1]*(k+1)%MOD)%MOD; }else fans = (fans + ans[i-l+1])%MOD; } ol(fans);puts(""); } return 0; }
相关文章推荐
- 2017 Multi-University Training Contest - Team 6 Classes
- 2017 Multi-University Training Contest - Team 10 1008-Monkeys(快速读入模板实例)
- HDU-6181 Two Paths(2017 Multi-University Training Contest - Team 10)
- hdoj 6045(2017 Multi-University Training Contest - Team 2) Is Derek lying?
- hdoj 6063(2017 Multi-University Training Contest - Team 3) RXD and math
- 2017 Multi-University Training Contest - Team 1 Balala Power!
- hdu 6034 Balala Power!(贪心)( 2017 Multi-University Training Contest - Team 1 )(无耻之sort)
- HDU6038 & 2017 Multi-University Training Contest - Team 1
- hdu 6047 Maximum Sequence(2017 Multi-University Training Contest - Team 2)
- hdu 6045 Is Derek lying?(2017 Multi-University Training Contest - Team 2)
- hdu 6053 TrickGCD [2017 Multi-University Training Contest - Team 2] [莫比乌斯函数]
- hdu 6055 Regular polygon(判断正方形)(2017 Multi-University Training Contest - Team 2)
- hdu 6041 I Curse Myself [2017 Multi-University Training Contest - Team 1]
- 【2017 Multi-University Training Contest - Team 6】Kirinriki
- 2017 Multi-University Training Contest - Team 3 - 1003
- hdu 6058 Kanade's sum(链表)(2017 Multi-University Training Contest - Team 3 )
- hdoj 6034(2017 Multi-University Training Contest - Team 1)Balala Power!
- hdu 6069 Counting Divisors(约数个数)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- 2017 Multi-University Training Contest - Team 4 1009 Questionnaire