/** 题目:hdu6069 Counting Divisors 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6069 题意:求[l,r]内所有数的k次方的约数个数之和。 思路: 用(1+e1)*(1+e2)*...*(1+en)的公式计算约数个数。 素数筛出[l,r]内的素因子,然后直接计算结果。(一开始我用vector存起来,之后再处理,结果超时, 时间卡的很紧的时候,vector也会很占用时间。) */ #include<iostream> #include<cstdio> #include<algorithm> #include<map> #include<vector> #include<queue> #include<cstring> #include<cmath> using namespace std; typedef pair<int,int> P; typedef long long LL; const int INF = 0x3f3f3f3f; const int mod = 998244353; const int maxn = 1e6+10; bool is_prime_small[maxn]; vector<int> v[maxn]; int prime[maxn], z; LL value[maxn], cnt[maxn]; void init() { for(int i = 2; i<=1000000; i++) is_prime_small[i] = true; z = 0; for(int i = 2; i<=1000000; i++){ if(is_prime_small[i]){ z++; prime[z] = i; } for(int j = 1; j <= z; j++){ if((LL)i*prime[j]>=1000000){ break; } is_prime_small[i*prime[j]] = false; if(i%prime[j]==0) break; } } } void segment_sieve(LL a,LL b,LL k) //[a,b) { for(int i = 0; i < b-a; i++) value[i] = i+a, cnt[i] = 1; int num; for(int i = 1; (LL)prime[i]*prime[i]<b&&i<=z; i++){ for(LL j = max((LL)prime[i],(a+prime[i]-1)/prime[i])*prime[i]; j < b; j+=prime[i]){ num = 0; while(value[j-a]%prime[i]==0){ num++; value[j-a]/=prime[i]; } cnt[j-a] = cnt[j-a]*(num*k+1)%mod; } } } LL solve(LL a,LL b,LL k) { LL ans = 0; for(int i = 0; i < b-a; i++){ if(value[i]>1){ cnt[i] = cnt[i] * (k+1) % mod; } ans = (ans + cnt[i])%mod; } return ans; } int main() { int T; cin>>T; init(); LL l, r, k; while(T--){ scanf("%lld%lld%lld",&l,&r,&k); if(l==r&&l==1){ printf("1 "); continue; } int flag = 0; if(l==1){ l++; flag = 1; } segment_sieve(l,r+1,k); printf("%lld ",(solve(l,r+1,k)+flag)%mod); } return 0; }