- 余明泽 的博客
2025年7月22日总结
- @ 2025-7-22 21:05:42
暑假集训 Day8 总结
E.序列查询
正解思路:
这道题目可以用到 multiset,十分简单,找小的就往前扫,找大的就往后扫。注意,最后输出要加星号。
AC 代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int q;
signed main() {
freopen("list.in", "r", stdin);
freopen("list.out", "w", stdout);
multiset<int> m;
cin >> q;
while (q--) {
int op;
cin >> op;
if (op == 1) {
int x;
cin >> x;
m.insert(x);
} else if (op == 2) {
int x, k;
cin >> x >> k;
auto it = m.upper_bound(x);
while (k-- && it != m.begin()) {
it--;
}
if (k >= 0 || it == m.end()) {
cout << "-1" << endl;
} else {
cout << *it << endl;
}
} else if (op == 3) {
int x, k;
cin >> x >> k;
auto it = m.lower_bound(x);
while (--k && it != m.end()) {
it++;
}
if (it == m.end()) {
cout << "-1" << endl;
} else {
cout << *it << endl;
}
}
}
return 0;
}
F.模i
正解思路:
这道题目可以用 dp 的做法。而由于数据范围过大,不能用三维 dp。所以我们可以用一个新的数组存储模数。用 表示把前 个元素分为 段的方案数。用 表示模 余数为 的 的和。接下来,我们枚举每一个 。对于当前的 得出 ,然后更新所有的 。接下来,更新所有的 为 。如果 那么统计答案,让 加上 ,最后输出 。
AC 代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 3e3+20;
const int M = 1e9+7;
int n, ans;
int a[N], sum[N];
int dp[N][N], cnt[N][N];
signed main() {
freopen("mod.in", "r", stdin);
freopen("mod.out", "w", stdout);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
sum[i] = sum[i - 1] + a[i];
}
dp[0][0] = 1;
cnt[1][0] = 1;
for (int j = 1; j <= n; j++) {
for (int i = 1; i <= j; i++) {
int m = sum[j] % i;
dp[i][j] = cnt[i][m];
}
for (int i = 1; i <= j; i++) {
int m = sum[j] % (i + 1);
cnt[i + 1][m] = (dp[i][j] + cnt[i + 1][m]) % M;
}
if (j == n) {
for (int i = 1; i <= n; i++) {
ans = (ans + dp[i][j]) % M;
}
}
}
cout << ans;
return 0;
}