In mathematics, the function
d(n)
d(n) denotes the number of divisors of positive integer
n
n.
For example, d(12)=6 d(12)=6 because 1,2,3,4,6,12 1,2,3,4,6,12 are all 12 12's divisors.
In this problem, given l,r l,r and k k, your task is to calculate the following thing :
For example, d(12)=6 d(12)=6 because 1,2,3,4,6,12 1,2,3,4,6,12 are all 12 12's divisors.
In this problem, given l,r l,r and k k, your task is to calculate the following thing :
(∑i=lrd(ik))mod998244353
(∑i=lrd(ik))mod998244353
In each test case, there are 3 3 integers l,r,k(1≤l≤r≤1012,r−l≤106,1≤k≤107) l,r,k(1≤l≤r≤1012,r−l≤106,1≤k≤107).
3 1 5 1 1 10 2 1 100 3
10 482302
本题刚开始看到感觉有点蒙
后来发现 其实d(x^k) = d((p1^k1*p2^k2*p2^k2*p3^k3...pn^kn)^k) = d(p1^(k1*k)*p2^(k2*k)*p2^(k2*k)*...pn^(kn*k))= (k1*k+1)*(k2*k+1)*(k3*k+1)*(k4*k+1)*...(kn*k+1)
再从l到r对d(i)求和
一开始的想法打算枚举l到r然后每个元素对质数进行试除 得到因子的指数 果断超时
后来又用了二分还是超时
原来这道题由于范围是l,r的最大范围是1e12 所以可以筛出1e6的质因子
然后枚举其中的质因子 将其定位到l到r的区间内 对l到r区间内的数字除此因子
然后记录质数 最后l到r里面剩下的合数都是1 质数不变 此时在枚举区间去指数求和求的答案
还是很巧妙的一个解法 枚举因子 而不是枚举区间
#include<bits/stdc++.h> using namespace std; const int MAXN= 1e6+10; const int mod = 998244353; typedef long long ll; ll t,size; ll l,r,k; ll prime[MAXN],cnt[MAXN],q[MAXN]; bool vis[MAXN]; void init() { for(int i=2;i<=1000000;i++) { if(!vis[i]){ prime[size++]=i; for(int j = i+i;j<=1000000;j+=i){ vis[j]=1; } } } } int main() { init(); // cout<<size<<endl; scanf("%d",&t); // freopen("out.txt","w",stdout); while(t--) { scanf("%lld%lld%lld",&l,&r,&k); ll ans = 0; if(l==1)ans++,l++; for(ll i=0;i<=r-l;i++)q[i] = l+i,cnt[i]=1; for(ll i=0;prime[i]*prime[i]<=r;i++) { ll lim = l/prime[i] + (l%prime[i]!=0); for(ll j=lim*prime[i];j<=r;j+=prime[i]) { ll tem = 0; while(q[j-l]%prime[i]==0)q[j-l]/= prime[i],tem++; cnt[j-l]=(cnt[j-l]*(tem*k+1)),cnt[j-l]%mod; } } for(ll i=0;i<=r-l;i++) { if(q[i]!=1)ans=(ans+cnt[i]*(k+1))%mod; else ans=(ans+cnt[i])%mod; } printf("%lld\n", ans%mod); } // fclose(stdout); return 0; }