[2017 Multi-University Training Contest - Team 4] HDU 6069 Counting Divisors
題目鏈接:
HDU 6069
題目大意:
給定
數據範圍:
解題思路:
我們將
那麼
因此, 我們可以先線性篩出
代碼:
//2017-08-04 13:37
//2017-08-04 14:00
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;
typedef long long LL;
const int MaxN = 1e6;
const int pt = 998244353;
int T;
LL l, r, k;
int prime[MaxN + 5];
LL num[MaxN + 5], sum[MaxN + 5];
int pcnt;
bool vis[MaxN + 5];
void getprime(){
for(int i = 2; i <= MaxN; i++){
if(!vis[i]) prime[++pcnt] = i;
for(LL j = 1; j <= pcnt && i * prime[j] <= MaxN; j++){
vis[i * prime[j]] = true;
if(i % prime[j] == 0) break;
}
}
}
int main(){
scanf("%d", &T);
getprime();
while(T--){
scanf("%lld %lld %lld", &l, &r, &k);
for(int i = 1; i <= r - l + 1; i++) num[i] = l + i - 1, sum[i] = 1;
LL tmp = sqrt(r);
for(int i = 1; i <= pcnt; i++){
LL x = l, p = prime[i];
if(p > tmp) break;
if(x % p != 0) x = x + p - x % p;
while(x <= r){
int pos = x - l + 1;
LL cnt = 0;
while(num[pos] % p == 0) cnt++, num[pos] /= p;
sum[pos] = sum[pos] * (cnt * k % pt + 1) % pt;
x += p;
}
}
LL ans = 0;
for(int i = 1; i <= r - l + 1; i++) if(num[i] > 1)
sum[i] = sum[i] * (k + 1) % pt;
for(int i = 1; i <= r - l + 1; i++) ans = (ans + sum[i]) % pt;
printf("%lld\n", ans);
}
return 0;
}
標籤: HDU 分解質因數 多校