B
考虑分类讨论:
- ,高斯求和公式即可。
- ,平方和公式,。
- ,由于 ,直接枚举所有可行情况,类似整除分块处理即可。
整除分块:把所有值相同的考虑到一起求和,时间复杂度 。
#include<cmath>
#include<cstdio>
#define int __int128
int init(){
char c = getchar();
int x = 0, f = 1;
for (; c < '0' || c > '9'; c = getchar())
if (c == '-') f = -1;
for (; c >= '0' && c <= '9'; c = getchar())
x = (x << 1) + (x << 3) + (c ^ 48);
return x * f;
}
void print(int x){
if (x < 0) x = -x, putchar('-');
if (x > 9) print(x / 10);
putchar(x % 10 + '0');
}
int sqr(int x){
return x * (x + 1) * (2 * x + 1) / 6;
}
int sum(int l, int r){
if (l > r) return 0;
int L = sqr(l - 1);
int R = sqr(r);
return ((l + r) * (r - l + 1) / 2) + 2 * (R - L);
}
int quick_mod(int a, int b){
int s = 1;
while (b) {
if (b & 1) s = s * a;
a = a * a; b >>= 1;
if (!b) break;
if (a > (int) 1e18) return (int) 1e18;
if (s > (int) 1e18) return (int) 1e18;
}
return s;
}
int mn(int x, int y){
return x < y ? x : y;
}
int mx(int x, int y){
return x > y ? x : y;
}
signed main(){
int l = init(), r = init(), k = init();
if (k == 1) {
print((l + r) * (r - l + 1) / 2);
return 0;
}
else if (k == 2) {
int i = (int) sqrt((double) l);
int j = (int) sqrt((double) r);
int s = sum(i + 1, j - 1);
print(s + (i * i + 2 * i - l + 1) * i + (r - j * j + 1) * j);
return 0;
}
else {
int ans = 0;
for (int i = 1; i; ++i) {
int L = quick_mod(i, k);
int R = quick_mod(i + 1, k) - 1;
if (R < l) continue;
if (L > r) break;
int num = mn(r, R) - mx(l, L) + 1;
ans += i * num;
}
print(ans), putchar('\n');
return 0;
}
}