716 订正
A 质数筛
#include<bits/stdc++.h>
using namespace std;
int n, m;
bool vis[5000005];
int ans[5000005], tot;
int main() {
freopen("number.in", "r", stdin);
freopen("number.out", "w", stdout);
cin >> n >> m;
for (int i = 2; i <= n; i++) {
for (int j = 2; j * i <= n; j++) {
if (vis[i * j])continue;
vis[i * j] = 1;
}
}
for (int i = 2; i <= n; i++)if (!vis[i])ans[++tot] = i;
cout << tot << " " << ans[m] << endl;
return 0;
}
B 快速求区间最大值
模拟40分。
正解: ST表 或 线段树
维护区间最大值 (建议) 可以用 ST图 。但这里的 ST图 维护下标。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int n, a[maxn], f[maxn][20], ans[maxn];
void stpre() {
for (int i = 1; i <= n; i++)f[i][0] = i;
for (int j = 1; (1 << j) <= n; ++j)
for (int i = 1; i + (1 << j) - 1 <= n; ++i)
if (a[f[i][j - 1]] > a[f[i + (1 << (j - 1))][j - 1]]) f[i][j] = f[i][j - 1];
else f[i][j] = f[i + (1 << (j - 1))][j - 1];
}//st表维护的是序号。
int query(int l,int r){
int k = log2(r - l + 1), m;
int x = f[l][k], y = f[r - (1 << k) + 1][k];
if (a[x] >= a[y]) m = x;
else m = y;
return m;
}
void dfs(int l, int r, int c) {
if (l < 1 || r > n || l > r) return;//不合法退出
if (l == r) {
ans[l] = c;return;}//已到底层
int maxx=query(l,r);
ans[maxx] = c;
dfs(l, maxx - 1, c + 1);
dfs(maxx + 1, r, c + 1);
}
int main() {
freopen("tower.in", "r", stdin);
freopen("tower.out", "w", stdout);
cin >> n;
for (int i = 1; i <= n; ++i)cin >> a[i];
stpre(),dfs(1, n, 0);
for (int i = 1; i <= n; ++i)cout<<ans[i]<<" ";
}
C 求出连续区间的数的中间值最大值
由于求得是中间值,显然与数的绝对大小无关,而与数的相对大小相关。
这道题的题目类似于 Acwing102 Best Cow Fences
借鉴此题的思想:
二分答案,判断“是否存在一个长度不小于 k k k 的子段,维护中间值最大”。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 99;
int n, k, a[N], l = 1, r, ans;
int sum[N];
bool check(int x) {
for (int i = 1; i <= n; i++) {
if (a[i] >= x) sum[i] = sum[i - 1] + 1;
else sum[i] = sum[i - 1] - 1;
}
int mn = 0;
for (int i = k; i <= n; i++) {
mn = min(mn, sum[i - k]);
if (sum[i] - mn > 0) return 1;
}
return 0;
}
int main() {
freopen("plunder.in", "r", stdin),freopen("plunder.out", "w", stdout);
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];r = max(r, a[i]);
}
for (int mid = (l + r) >> 1; l <= r; mid = (l + r) >> 1) {
if (check(mid)) ans = mid, l = mid + 1;
else r = mid - 1;
}
cout << ans;
}
D dp(雾)
#include<bits/stdc++.h>
using namespace std;
#define N 1000000
struct node {
int x, id, dis;
};
int n, m, k, trans[N], dis[N][21], ans = 0x3f3f3f3f;
deque<node> q;
void bfs(int n, int m, int k, int start) {
q.push_back({
start, 0, 0});
dis[start][0] = 0;
while (!q.empty()) {
node cur = q.front();
q.pop_front();
if ( dis[cur.x][cur.id] < cur.dis ) continue;
if (trans[cur.x] != cur.x && cur.id < k && dis[trans[cur.x]][cur.id + 1] > cur.dis) {
dis[trans[cur.x]][cur.id + 1] = cur.dis;
q.push_front({
trans[cur.x], cur.id + 1, cur.dis});
}
for (int i = max(1, cur.x - m); i <= min(n, cur.x + m); ++i)
if (dis[i][cur.id] > cur.dis + 1) {
dis[i][cur.id] = cur.dis + 1;
q.push_back({
i, cur.id, cur.dis + 1});
}
}
}
int main() {
freopen("step.in", "r", stdin), freopen("step.out", "w", stdout);
memset(dis, 0x3f3f3f3f, sizeof(dis));
cin >> n >> m >> k;
for (int i = 1; i <= n; ++i)cin >> trans[i];
bfs(n, m, k, 1);
for (int i = 0; i <= k; ++i)ans = min(ans, dis[n][i]);
cout << ans;
}
E 抉择
真是没看懂,等大佬给我讲懂了写(坑++)