716测试寄

请添加图片描述

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 抉择

真是没看懂,等大佬给我讲懂了写(坑++)
请添加图片描述

猜你喜欢

转载自blog.csdn.net/skyflying266/article/details/125820454