题目描述
思路
套路枚举
换元
利用 化简
设
令
观察这个柿子,那么有两个函数可以线性筛 与 ,那么线性筛即可(没学过线性筛的可以看
P4449 于神之怒加强版 )
代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e7 + 10;
const long long Mod = 2147483658;
long long N , K , T , n;
int Prime[MAXN / 10] , Cnt;
unsigned int F[MAXN] , S[MAXN];
bitset<MAXN> Vis;
unsigned int Quick_Power(int x , int mi) {
unsigned int Ans = 1;
for(; mi ; mi >>= 1, x = 1ll * x * x)
if(mi & 1) Ans = 1ll * Ans * x;
return Ans;
}
void Get_Function(int N) {
F[1] = S[1] = 1;
for(int i = 2; i <= N; i++) {
if(!Vis[i]) {
Prime[++Cnt] = i;
S[i] = Quick_Power(i , K);
F[i] = i - 1;
}
for(int j = 1; j <= Cnt && Prime[j] * i <= N; j++) {
Vis[i * Prime[j]] = 1;
S[i * Prime[j]] = 1ll * S[i] * S[Prime[j]];
if(i % Prime[j] == 0) {
if(i / Prime[j] % Prime[j] != 0)
F[i * Prime[j]] = -Prime[ j ] * F[i / Prime[j]];
break;
}
F[i * Prime[j]] = F[i] * F[Prime[j]];
}
}
for(int i = 2; i <= N; i++) {
F[i] = (F[i] * S[i] + F[i - 1]);
S[i] = (S[i] + S[i - 1]);
}
for(int i = 2; i <= N; i++) {
S[i] = (S[i] + S[i - 1]);
}
}
int Sum(int n) {
return S[n << 1] - (S[n] << 1);
}
unsigned int AC(int n) {
unsigned int Ans = 0;
for(int l = 1 , r; l <= n; l = r + 1) {
r = n / (n / l);
Ans += (F[r] - F[l - 1]) * Sum(n / l);
}
return Ans;
}
int main() {
scanf("%u%u%u" ,&T ,&N ,&K);
Get_Function(N << 1);
while(T--) {
scanf("%u" ,&n);
printf("%u\n" ,AC(n));
}
return 0;
}