【Link】:
【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】#includeusing 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 pii;typedef pair 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 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;}