C. 2026
注意到 \(0 < x < y < \sqrt{n}\),所以直接枚举 \((x, y)\) 即可
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> cnt(n+1);
for (int x = 1; x*x < n; ++x) {
for (int y = x+1; x*x+y*y <= n; ++y) {
cnt[x*x+y*y]++;
}
}
vector<int> ans;
for (int i = 1; i <= n; ++i) {
if (cnt[i] == 1) ans.push_back(i);
}
cout << ans.size() << '\n';
for (int x : ans) cout << x << ' ';
return 0;
}
D. Kadomatsu Subsequence
统计合法的 \((j, ?, ?)\) 和 \((?, ?, j)\) 的个数
对于 \(i\) 和 \(k\) 的顺序无所谓
\(7:5:3\) 可以看成是 \(7x:5x:3x\)
通过枚举 \(j\),我们可以得知 \(x=\frac{a_j}{5}\)
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
int main() {
int n;
cin >> n;
vector<int> a(n);
rep(i, n) cin >> a[i];
ll ans = 0;
rep(ri, 2) {
map<int, int> cnt;
for (int na : a) {
cnt[na]++;
if (na%5 == 0) {
int x = na/5;
ans += (ll)cnt[x*3]*cnt[x*7];
}
}
reverse(a.begin(), a.end());
}
cout << ans << '\n';
return 0;
}
E. Kite
其实就是求 \((A_i, B_i)\) 的最长上升子序列
注意到,当 \(A_i = A_j\) 时,也算冲突
如果将 \(A_i\) 作为第一关键字做升序,将 \(B_i\) 作为第二关键字也做升序排序的话,就会产生上面的冲突。解决办法是将 \(B_i\) 作为第二关键字做降序排序
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using P = pair<int, int>;
int main() {
int n;
cin >> n;
vector<P> ab;
rep(i, n) {
int a, b;
cin >> a >> b;
ab.emplace_back(-a, b);
}
sort(ab.begin(), ab.end(), greater<>());
vector<int> b;
rep(i, n) b.push_back(ab[i].second);
const int INF = 1001001001;
vector<int> dp(n+1, INF);
dp[0] = -1;
int ans = 0;
for (int nb : b) {
int i = lower_bound(dp.begin(), dp.end(), nb) - dp.begin();
dp[i] = nb;
ans = max(ans, i);
}
cout << ans << '\n';
return 0;
}
F. Beautiful Kadomatsu
不难发现,峰和谷是交替出现的,那么为了保证峰比谷多,只需让首尾都是峰就行,也就是开头两个数升序,末尾两个数降序。对于中间的数随意。
那么答案就是 \(\sum\limits_{l < r} a_lb_r2^{r-l-1} + \sum a_ib_i\),其中 \(a_i\) 表示 \(i\) 左边 \(< p_i\) 的数的个数,\(b_i\) 表示 \(i\) 右边 \(< p_i\) 的数的个数
代码实现
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using mint = modint998244353;
int main() {
int n;
cin >> n;
vector<int> p(n);
rep(i, n) cin >> p[i], p[i]--;
vector<mint> a(n), b(n);
{
fenwick_tree<int> t(n);
rep(i, n) {
a[i] = t.sum(0, p[i]);
t.add(p[i], 1);
}
}
{
fenwick_tree<int> t(n);
for (int i = n-1; i >= 0; --i) {
b[i] = t.sum(0, p[i]);
t.add(p[i], 1);
}
}
vector<mint> two(n+1, 1), owt(n+1);
rep(i, n) two[i+1] = two[i]*2;
owt[n] = two[n].inv();
for (int i = n; i >= 1; --i) owt[i-1] = owt[i]*2;
mint ans, lsum;
rep(i, n) {
ans += lsum*b[i]*two[i];
ans += a[i]*b[i];
lsum += a[i]*owt[i+1];
}
cout << ans.val() << '\n';
return 0;
}
浙公网安备 33010602011771号