2026.2.24 雅礼总结

2026.2.24 雅礼总结

今天挂分的绝对值竟然是200。

太可怕了。

题目 A B C D
估分 100 100 [0, 100) [0,100)
实际 100 100 100 100

A

语法题,只要你学过语文且会if判断以及输入输出就行。

B

调了 \(114514\) 个小时后,没调出来,但是后面冷静思考后发现竟然有规律。

在第 \(x\ mod \ n\) 次移动时,就会减去 \(a_{n\ -\ (x\ mod\ n)}\ \oplus\ a_{n\ -\ (x\ mod\ n)\ +\ 1}\)

同时,也会加上一个数异或另一个数,但是这个数我感觉不好分析。

该怎么办呢?

在纸上模拟过程,发现每次要加的异或值都是 \(n - 1\) 个。

所以,我们可以先将所有的 \(n\) 个异或值相加,然后只用考虑减了。

注意,要开 longlong

//ÎÑÒªÑÊÅÆ
//ÎÑÒªÑÊÅÆ
#include <bits/stdc++.h>
using ll = long long;
#define f first
#define s second
const int inf = (1 << 30) - 1;
const ll INF = 1ll << 62;

const int N = 1e5 + 10;
int n, m, x, k;
ll sum, a[N], b[N];

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	std::cin >> n >> m;
	for (int i = 1; i <= n; i++) std::cin >> a[i];
	a[n + 1] = a[1];
	for (int i = 1; i <= n; i++) sum += a[i] ^ a[i + 1], b[n - i] = a[i] ^ a[i + 1];//初始将所有的异或值相加,包括a[n] ^ a[1]
	std::cout << sum - b[0] << ' ';
	for (int i = 1; i <= m; i++) {
		int x;
		std::cin >> x, k = (k + x) % n;
		std::cout << sum - b[k] << ' ';
	}
}

C

第一眼看:这肯定是特别难的数学题。

但是 \(l, r\) 最大只有 \(10^7\) ,可以枚举最后的答案。
因为题目要求最大,所以倒序枚举答案 \(i\)

然后接下来就是要确保 \(l, r\) 之间能找到至少两个 \(i\) 的倍数。

我们就可以找到第一个大于 \(l\)\(i\) 的倍数,也就是 \(\left\lfloor \frac{l-1}{i} \right\rfloor + 1\)

再找的第一个小于 \(r\)\(i\) 的倍数, 也就是 \(\left\lfloor \frac{r}{i} \right\rfloor\)

最后判是否合法就行了。

//ÎÑÒªÑÊÅÆ
//ÎÑÒªÑÊÅÆ
//ÎÑÒªÑÊÅÆ
#include <bits/stdc++.h>
using ll = long long;
#define f first
#define s second
const int inf = (1 << 30) - 1;
const ll INF = 1ll << 62;

int l, r;

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);	
	std::cin >> l >> r;
	for (int i = r; i >= 1; i--) if ((l - 1) / i + 1 < r / i) std::cout << i << '\n', exit(0);
}

D

就是清新小大炮。

\(dp[i][0, 1]\) 是修改前的升降,\(dp[i][2, 3]\) 是修改后的升降。

然后就可以转移了。

感觉大炮确实是有点大炮打蚊子,所以讲了一下贪心。

//ÎÑÒªÑÊÅÆ
//ÎÑÒªÑÊÅÆ
//ÎÑÒªÑÊÅÆ
//ÎÑÒªÑÊÅÆ 
#include <bits/stdc++.h>
using ll = long long;
#define f first
#define s second
const int inf = (1 << 30) - 1;
const ll INF = 1ll << 62;

const int N = 1e5 + 10;
int n, a[N];
ll dp[N][4];

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	std::cin >> n;
	if (n <= 2) return std::cout << "0\n", 0;
	dp[1][2] = dp[1][3] = 1;
	for (int i = 1; i <= n; i++) {
		std::cin >> a[i];
		dp[i][0] = dp[i - 1][2], dp[i][1] = dp[i - 1][3];
		if (a[i] > a[i - 1]) dp[i][0] = std::min(dp[i][0], dp[i - 1][1]); 
		if (a[i] < a[i - 1]) dp[i][1] = std::min(dp[i][1], dp[i - 1][0]);
		dp[i][2] = std::min(dp[i - 1][0], dp[i - 1][3]) + 1;
		dp[i][3] = std::min(dp[i - 1][1], dp[i - 1][2]) + 1;
	}
	std::cout << std::min({dp[n][0], dp[n][1], dp[n][2], dp[n][3]}) << '\n';
} 

但是也可以用贪心做。

根据dyc的思路,最后的数组就两个状态,只需要根据这两个状态求出操作数然后取 \(\min\) 就好了。

posted @ 2026-02-24 22:57  yixinc  阅读(7)  评论(0)    收藏  举报