hdu 6069 Counting Divisors
题意:给出求L,R 之间的数的K次方的因子数之和
思路:打表求出1~10^6之间的素数,枚举[L,R]之间素数的倍数,然后按算数基本定理求出因子个数和。处理过后[L,R]之间的数要么是1,要么是一个素数,再次根据算数基本定理计算因子个数和。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define MAXSIZE 1000015 #define INF 0x3f3f3f3f #define LL long long #define MOD 998244353 using namespace std; bool vis[MAXSIZE]; LL p[MAXSIZE],a[MAXSIZE],b[MAXSIZE]; int n,cns; void GetPrime() { cns = 1; memset(vis,false,sizeof(vis)); vis[1] = true; for(int i=2;i<MAXSIZE;i++) { if(vis[i] == false) { p[cns++] = i; for(int j=i*2;j<MAXSIZE;j+=i) { vis[j] = true; } } } } int main() { GetPrime(); LL l,r,k,ans; int T; scanf("%d",&T); while(T--) { scanf("%lld%lld%lld",&l,&r,&k); ans = 0; for(LL i=l;i<=r;i++) { a[i-l] = i; //记录这个数的值 b[i-l] = 1; //记录正因子个数 } for(int i=1;p[i]*p[i]<=r && i<=cns;i++) //枚举素数 { LL j = l/p[i] + (l%p[i]!=0); for(j=j*p[i];j<=r;j+=p[i]) //枚举素数的倍数 { LL sum = 0; while(a[j-l]%p[i] == 0) { sum++; a[j-l]/=p[i]; } b[j-l] = (b[j-l]*((sum*k%MOD + 1)%MOD))%MOD; } } for(LL i=l;i<=r;i++) { if(a[i-l] == 1) ans = (ans+b[i-l])%MOD; else ans = (ans+b[i-l]*(k+1)%MOD)%MOD; } printf("%lld\n",ans); } return 0; }