NC222912. 小䓤的凸包
描述
输入描述
共一行五个整数
输出描述
一个整数表示每组询问的答案
示例1
输入:
2 4 3 1 1
输出:
3
说明:
与题目中举的例子相同示例2
输入:
50 2 5 4 3
输出:
928433684
示例3
输入:
500000 3 4 2 2
输出:
15675121
C++ 解法, 执行用时: 3149ms, 内存消耗: 218760K, 提交时间: 2021-11-19 21:55:42
#include <bits/stdc++.h> using namespace std; typedef long long s64; const int N = 1e8 + 5, D = 998244353; s64 pow_mod(s64 x, int y = D - 2) { s64 ans = x; --y; while (y) { if (y & 1) ans = ans * x % D; x = x * x % D; y >>= 1; } return ans; } int n; char miu[N]; bool mark[N]; int pr[N / 10], pcnt; void init(int n) { miu[1] = 1; for (int i = 2; i <= n; ++i) { if (!mark[i]) { pr[++pcnt] = i; miu[i] = -1; } for (int j = 1; j <= pcnt; ++j) { int p = pr[j]; if (i * p > n) break; mark[i * p] = 1; if (i % p == 0) break; miu[i * p] = -miu[i]; } } } int q[N]; s64 F(int n, int x, int y, int a, int b) { if (y > x) y = x = 1; int t = 0; int i = 1; while (i <= n) { q[++t] = i; i = n / (n / i) + 1; } q[t + 1] = n + 1; int j = 0; s64 ans = 0; s64 w2 = 0, s_i = 0; i = 0; for (int h = t; h; --h) { int d = q[h]; int m = n / d; s64 w1 = 0; for (int i = d; i < q[h + 1]; ++i) if (miu[i] == 1) w1 += pow_mod(i, a + b); else if (miu[i] == -1) w1 -= pow_mod(i, a + b); w1 %= D; while (j < m) { ++j; while ((s64)(i + 1) * x < (s64)y * j) { ++i; (s_i += pow_mod(i, a)) %= D; } (w2 += pow_mod(j, b) * s_i) %= D; } (ans += w1 * w2) %= D; } return ans; } int main() { #ifdef kcz freopen("1.in", "r", stdin); //freopen("1.out","w",stdout); #endif int x, y, a, b; cin >> n >> y >> x >> a >> b; int d = __gcd(x, y); x /= d; y /= d; init(n); s64 ans = F(n, x, y, a, b); if (y > x) { ans = (ans + 1 + F(n, 1, 1, b, a) - F(n, y, x, b, a)) % D; } else if (x <= n && y <= n) (ans += pow_mod(y, a) * pow_mod(x, b)) %= D; cout << (ans % D + D) % D << endl; }