NOTE
A - Sieve of Erato67henes
关键词:签到
Code
// Problem: CF 2195 A// Contest: Codeforces - Codeforces Round 1080 (Div. 3)// URL: https://codeforces.com/contest/2195/problem/A// Time: 2026-05-08 14:17:57#include <bits/stdc++.h>using namespace std;
// clang-format off#define endl '\n'#define all(x) (x).begin(), (x).end()#define fastio() ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);// clang-format on
using ll = long long;using ull = unsigned long long;using pii = pair<int, int>;using pdd = pair<double, double>;using pll = pair<long long, long long>;
const int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1};const int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};const int inf = 0x3f3f3f3f;const int N = 0;
void solve(){ int n; cin >> n;
bool fl = false;
for (int i = 0; i < n; i++) { int x; cin >> x; if (x == 67) fl = true; }
if (fl) cout << "YES" << endl; else cout << "NO" << endl;}
int main(){ fastio();
int T = 1; cin >> T;
while (T--) solve();
return 0;}B - Heapify 1
关键词:模拟
思路
由于只能交换下标为 倍关系的数,所以可交换的次数其实不多。暴力即可。
Code
// Problem: CF 2195 B// Contest: Codeforces - Codeforces Round 1080 (Div. 3)// URL: https://codeforces.com/contest/2195/problem/B// Time: 2026-05-08 15:19:19#include <bits/stdc++.h>using namespace std;
// clang-format off#define endl '\n'#define all(x) (x).begin(), (x).end()#define fastio() ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);// clang-format on
using ll = long long;using ull = unsigned long long;using pii = pair<int, int>;using pdd = pair<double, double>;using pll = pair<long long, long long>;
const int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1};const int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};const int inf = 0x3f3f3f3f;const int N = 0;
void solve(){ int n; cin >> n;
vector<int> a(n + 1); for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) for (int j = i; j <= n; j *= 2) for (int k = i * 2; k <= n; k *= 2) if (a[k / 2] > a[k]) swap(a[k / 2], a[k]);
if (is_sorted(all(a))) cout << "YES" << endl; else cout << "NO" << endl;}
int main(){ fastio();
int T = 1; cin >> T;
while (T--) solve();
return 0;}C - Dice Roll Sequence
关键词:思维,贪心
思路
注意到两个整数位于相邻面,当且仅当 并且 。并且注意到对于任意的两个面,总存在第三个面和两者均相邻。
考虑遍历 ,如果 或 ,就一定要有一个值被修改,如果修改 ,后续的 和 可能还有问题,根据上面的结论,我们修改中间的 即可。可以把 改成 表示已修改,也可以 i++ 跳过。
Code
// Problem: CF 2195 C// Contest: Codeforces - Codeforces Round 1080 (Div. 3)// URL: https://codeforces.com/contest/2195/problem/C// Time: 2026-05-08 16:25:33#include <bits/stdc++.h>using namespace std;
// clang-format off#define endl '\n'#define all(x) (x).begin(), (x).end()#define fastio() ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);// clang-format on
using ll = long long;using ull = unsigned long long;using pii = pair<int, int>;using pdd = pair<double, double>;using pll = pair<long long, long long>;
const int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1};const int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};const int inf = 0x3f3f3f3f;const int N = 0;
void solve(){ int n; cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
int res = 0; for (int i = 1; i < n; i++) { if (a[i - 1] + a[i] == 7 || a[i - 1] == a[i]) res++, i++; }
cout << res << endl;}
int main(){ fastio();
int T = 1; cin >> T;
while (T--) solve();
return 0;}D - Absolute Cinema
关键词:数学,推公式,差分
思路
NOTE对于绝对值函数求和的式子,可以从数学的角度看。
对于这样的函数 ,一阶导数是斜率,在 处突变。对于 ,除了 这个“拐点”之外,其他所有地方的二阶导数都是 。只有在 处,斜率从 瞬间跳变到 (变化量为 )。
既然我们想求 ,我们只需要对 求二阶导数。因为在 这个点,其他所有的项 () 的二阶导数都是 ,只有 在这里会暴露出 的值。
而一阶导数对应一维差分,二阶导数对应二维差分,因此对 做两次差分就能提取 。
首尾两项比较特殊,需要单独求解。

Code
// Problem: CF 2195 D// Contest: Codeforces - Codeforces Round 1080 (Div. 3)// URL: https://codeforces.com/contest/2195/problem/D// Time: 2026-05-12 17:42:57#include <bits/stdc++.h>using namespace std;
// clang-format off#define endl '\n'#define all(x) (x).begin(), (x).end()#define fastio() ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);// clang-format on
using ll = long long;using ull = unsigned long long;using pii = pair<int, int>;using pdd = pair<double, double>;using pll = pair<long long, long long>;using i128 = __int128;
const int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1};const int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};const int inf = 0x3f3f3f3f;const int N = 3e5 + 10;
ll a[N], res[N];
void solve(){ ll n; cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n - 2; i++) res[i + 1] = (a[i] - a[i + 1] - (a[i + 1] - a[i + 2])) / 2;
ll sum1 = 0, sum2 = 0; for (int i = 2; i < n; i++) { sum1 = sum1 + (n - i) * res[i]; sum2 = sum2 + (i - 1) * res[i]; }
cout << (a[n] - sum1) / (n - 1) << " ";
for (int i = 2; i < n; i++) cout << res[i] << " ";
cout << (a[1] - sum2) / (n - 1) << endl;}
int main(){ fastio();
int T = 1; cin >> T;
while (T--) solve();
return 0;}E - Idiot First Search
关键词:树形DP,dfs
思路
Step 1 - 完整遍历一个空子树的代价
首先我们先不考虑起点,假设 Bob 按照规则,从父节点正常进入了一个完全空白的子树 ,模拟一下他的流程。
-
他会给 写上 ‘L’,然后进入左子树。
-
左子树也是空白的,他会把左子树完整遍历一遍,最终退回到 。
-
此时 上是 ‘L’,他改成 ‘R’,进入右子树。
-
右子树完整遍历后,再次退回到 。
-
此时 上是 ‘R’,他擦除掉,退回到 的父节点。
我们发现,当他完整遍历完一个子树并退出时,这个子树里的所有节点都会恢复成初始的空白状态。
那么遍历整个子树 并退回父节点,总共需要多少步(秒)?每经过一条边(向下或向上)都需要 1 秒。在一棵大小为 的子树中,共有 条边。每条边都会走两遍,再加上最初进入 和最后离开 的 2 步,总时间为:
Step 2 - 从起点第一次到父节点的代价
现在考虑 Bob 的起点是 ,它会先遍历完左子树,再遍历完右子树,最后走向父节点。
总代价为:。由于 ,因此对于任意的起点 ,Bob 需要消耗 的代价走到起点 的父节点。
TIP注意:当 Bob 离开 节点到达父节点时, 节点和它的整棵子树都恢复到了完全空白的状态。
Step 3 - 到达父节点后
现在 Bob 从 到达了父节点 ,父节点此刻是空白的。根据他的运动规则,应该写下 ‘L’,然后走到左边,遍历完左边整棵子树以后再走到右边,也就是说他会再次走一遍 ,考虑在 节点花费的时间,就是
Step 4 - 推公式
对于从任意节点 出发,Bob 向上“逃脱”的过程就是:
- 逃出 到达 :耗时
- 逃出 到达 :耗时
- 逃出 到达 :耗时
- 直到到达节点 1,逃出节点 1 到达最终目的地 0:耗时 。
所以,如果以 表示从节点 到达节点 的总时间,公式为:
Code
// Problem: CF 2195 E// Contest: Codeforces - Codeforces Round 1080 (Div. 3)// URL: https://codeforces.com/contest/2195/problem/E// Time: 2026-05-13 13:08:58#include <bits/stdc++.h>using namespace std;
// clang-format off#define endl '\n'#define all(x) (x).begin(), (x).end()#define fastio() ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);// clang-format on
using ll = long long;using ull = unsigned long long;using pii = pair<int, int>;using pdd = pair<double, double>;using pll = pair<long long, long long>;using i128 = __int128;
const int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1};const int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};const int inf = 0x3f3f3f3f;const int N = 0;const ll mod = 1e9 + 7;
void solve(){ int n; cin >> n;
vector<int> l(n + 1), r(n + 1); for (int i = 1; i <= n; i++) cin >> l[i] >> r[i];
vector<ll> sz(n + 1, 0);
// 计算每个节点子树大小 auto dfs = [&](auto &self, int u) -> void { sz[u] = 1;
if (l[u]) { self(self, l[u]); sz[u] += sz[l[u]]; }
if (r[u]) { self(self, r[u]); sz[u] += sz[r[u]]; } };
dfs(dfs, 1); // 注意实际能遍历的根节点还是 1
vector<ll> dp(n + 1, 0);
// 自顶向下计算路径前缀和 dp[u] auto dfss = [&](auto &self, int u, ll cur) -> void { ll t = (2 * sz[u] - 1) % mod; dp[u] = (cur + t) % mod;
if (l[u]) self(self, l[u], dp[u]); if (r[u]) self(self, r[u], dp[u]); };
dfss(dfss, 1, 0);
for (int i = 1; i <= n; i++) cout << dp[i] << " ";
cout << endl;}
int main(){ fastio();
int T = 1; cin >> T;
while (T--) solve();
return 0;}