B
先排序,考虑枚举两个位置,计算这两个位置差的贡献。
。
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
constexpr int P = 998244353;
vector<i64> fac, ifac;
i64 power(i64 a, i64 b, int p = P) {
i64 res = 1;
for (; b; b >>= 1, a = a * a % p) {
if (b & 1) {
res = res * a % p;
}
}
return res;
}
i64 inv(i64 x) {
return power(x, P - 2);
}
void init(int N) {
fac.assign(N + 1, 0);
ifac.assign(N + 1, 0);
fac[0] = 1;
for (int i = 1; i <= N; i++) {
fac[i] = fac[i - 1] * i % P;
}
ifac[N] = inv(fac[N]);
for (int i = N - 1; i >= 0; i--) {
ifac[i] = ifac[i + 1] * (i + 1) % P;
}
}
i64 C(int n, int m) {
if (m < 0 || m > n) {
return 0;
}
return fac[n] * ifac[m] % P * ifac[n - m] % P;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
init(4E3);
int n;
cin >> n;
vector<int> a(n), b(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int i = 0; i < n; i++) {
cin >> b[i];
}
sort(a.begin(), a.end());
sort(b.begin(), b.end());
i64 ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int x1 = i, y1 = j;
int x2 = n - 1 - i, y2 = n - 1 - j;
ans = (ans + abs(a[i] - b[j]) * C(x1 + y1, min(x1, y1)) % P * C(x2 + y2, min(x2, y2) % P)) % P;
}
}
cout << ans << '\n';
return 0;
}
C
。
为偶数:。
为奇数:。
问题转化为求 中因子 的个数,直接求 的个数就行, 的个数肯定比较少。
即计算:
这个式子可以直接算。
为奇数多算个 。
floor_sum(n, m, a, b)
It returns
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
using i128 = __int128;
ostream &operator<<(ostream &os, const i128 &v) {
if (v <= 1000000000000000000) {
return os << i64(v);
}
return os << i64(v / 1000000000000000000) << setw(18) << setfill('0') << i64(v % 1000000000000000000);
}
i128 floor_sum(i128 n, i128 m, i128 a, i128 b) {
i128 ans = 0;
if (a < 0) {
i128 a2 = (a % m + m) % m;
ans -= n * (n - 1) / 2 * ((a2 - a) / m);
a = a2;
}
if (b < 0) {
i128 b2 = (b % m + m) % m;
ans -= n * ((b2 - b) / m);
b = b2;
}
while (1) {
if (a >= m) {
ans += n * (n - 1) / 2 * (a / m);
a %= m;
}
if (b >= m) {
ans += n * (b / m);
b %= m;
}
i128 y_max = a * n + b;
if (y_max < m) {
break;
}
n = y_max / m;
b = y_max % m;
swap(m, a);
}
return ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
i64 n;
cin >> n;
i128 ans = 0;
if (n % 2 == 1) {
for (i64 p = 5; p <= n; p *= 5) {
ans += (n / p + 1) / 2;
}
n--;
}
for (i64 p = 5; p <= n; p *= 5) {
ans += floor_sum(n / 2, p, 2, 2);
}
cout << ans << '\n';
return 0;
}
E
考虑从左到右扫,只要当前和为偶数就把它切开,这样就可以知道这个区间最多能分成多少个偶数部分。
前缀和,。
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
void solve() {
int n, q;
cin >> n >> q;
vector<int> a(n);
for (int i = 0; i < n; i++) {
int x;
cin >> x;
a[i] = x % 2;
}
vector<int> sum(n + 1);
for (int i = 0; i < n; i++) {
sum[i + 1] = sum[i] + a[i];
}
vector<array<int, 2>> cnt(n + 1);
for (int i = 0; i < n; i++) {
cnt[i + 1] = cnt[i];
cnt[i + 1][sum[i + 1] % 2]++;
}
for (int i = 0; i < q; i++) {
int l, r, k;
cin >> l >> r >> k;
l--;
if ((sum[r] - sum[l]) % 2 == 0 && cnt[r][sum[r] % 2] - cnt[l][sum[l] % 2] >= k) {
cout << "YES\n";
} else {
cout << "NO\n";
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
G
发现 是 倍数才有可能是 YES,又发现若 ,除非 有一个为 才 YES,因为限制操作 。
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
void solve() {
int x, y, z;
cin >> x >> y >> z;
int g = gcd(x, y);
if (x == z || y == z || (z != 0 && z % g == 0)) {
cout << "YES\n";
} else {
cout << "NO\n";
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}