VP CodeForces
CF1941B Rudolf and 121
给定一个长度为
的序列 。求最少进行多少次操作后所有 :
- 选择一个
,并让 。
我们记选择
发现
此时
同理,对于
同理依次操作
时间复杂度
void Luogu_UID_748509() {
int n; fin >> n;
vector<int> a(n);
fin >> a;
for (int i = 0; i + 2 < n; ++ i ) {
if (a[i] < 0) {
puts("NO");
return;
}
a[i + 1] -= a[i] * 2;
a[i + 2] -= a[i];
a[i] = 0;
}
puts(a[n - 2] || a[n - 1] ? "NO" : "YES");
}
CF1941D Rudolf and the Ball Game
有
个人围成一圈。最开始第 个人拿着一个球。 接下来会发生
个事件,每个事件形如 ,其中:
表示当前手中有球的人将球顺时针传给第 个人。 表示当前手中有球的人将球逆时针传给第 个人。 表示这个事件不清楚,当前手中有球的人将球顺时针或逆时针传给第 个人。 求最终哪些人可能有球。
我们设 bool 状态
转移极易,我们令
最后看哪些
时空复杂度均
int n, m, x;
int dis;
char op;
bool st[110][N];
int F(int a, int b) {
return ((a + b) % n + n) % n;
}
void Luogu_UID_748509() {
fin >> n >> m >> x;
// for (int j = 0; j <= m; ++ j )
for (int i = 0; i < n; ++ i )
st[0][i] = st[1][i] = 0;
st[0][x - 1] = true;
for (int j = 1; j <= m; ++ j ) {
cin >> dis >> op;
for (int i = 0; i < n; ++ i )
if (st[j - 1 & 1][i]) {
if (op != '1') st[j & 1][F(i, dis)] = true;
if (op != '0') st[j & 1][F(i, -dis)] = true;
st[j - 1 & 1][i] = 0;
}
}
int res = 0;
for (int i = 0; i < n; ++ i ) res += st[m & 1][i];
fout << res << '\n';
for (int i = 0; i < n; ++ i ) if (st[m & 1][i]) fout << i + 1 << ' ';
puts("");
}
CF1941E Rudolf and k Bridges
有一条
的河。第 行第 列的深度为 。保证 。 如果在第
行第 列安置桥墩,所需代价为 。 你需要选择连续的
行,每行都要架起若干个桥墩,并满足以下条件:
- 每行的第
列必须架桥墩; - 每行的第
列必须架桥墩; - 每行的相邻两个桥墩的距离不超过
。其中 和 之间的距离为 。 求最小代价和。
行与行之间架桥墩并无关系。我们可以求出第
对于每一行分别 DP,当前是第
发现后面的
总时间复杂度为
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
typedef unsigned long long LL;
typedef pair<int, int> PII;
struct FASTREAD {
template <typename T>
FASTREAD& operator >>(T& x) {
x = 0; bool flg = false; char c = getchar();
while (c < '0' || c > '9') flg |= (c == '-'), c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
if (flg) x = -x; return *this;
}
template <typename T>
FASTREAD& operator >>(vector<T>& x) {
for (auto it = x.begin(); it != x.end(); ++ it ) (*this) >> *it;
return *this;
}
}fin;
struct FASTWRITE {
template <typename T>
FASTWRITE& operator <<(T x) {
if (x < 0) x = -x, putchar('-');
static int buf[35]; int top = 0;
do buf[top ++ ] = x % 10, x /= 10; while (x);
while (top) putchar(buf[ -- top] + '0');
return *this;
}
FASTWRITE& operator <<(char x) {
putchar(x); return *this;
}
template <typename T>
FASTWRITE& operator <<(vector<T> x) {
for (auto it = x.begin(); it != x.end(); ++ it ) (*this) << *it, putchar(' ');
putchar('\n');
return *this;
}
}fout;
const int N = 110, M = 2e5 + 10;
const int P = 998244353;
int n, m, k, d;
int a[N][M];
int sum[N];
int f[M];
struct Tree {
int l, r, v;
}tr[M << 2];
void pushup(int u) {
tr[u].v = min(tr[u << 1].v, tr[u << 1 | 1].v);
}
void build(int u, int l, int r) {
tr[u] = {l, r, 0};
if (l == r) tr[u].v = 0;
else {
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
}
}
void modify(int u, int x, int d) {
if (tr[u].l == tr[u].r) tr[u].v += d;
else {
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid) modify(u << 1, x, d);
else modify(u << 1 | 1, x, d);
pushup(u);
}
}
int query(int u, int l, int r) {
if (tr[u].l >= l && tr[u].r <= r) return tr[u].v;
int mid = tr[u].l + tr[u].r >> 1, res = 1e18;
if (l <= mid) res = query(u << 1, l, r);
if (r > mid) res = min(res, query(u << 1 | 1, l, r));
return res;
}
void Luogu_UID_748509() {
fin >> n >> m >> k >> d;
for (int i = 1; i <= n; ++ i ) {
for (int j = 1; j <= m; ++ j ) fin >> a[i][j];
build(1, 1, m);
f[1] = a[i][1] + 1;
modify(1, 1, f[1]);
for (int j = 2; j <= m; ++ j ) {
f[j] = a[i][j] + 1 + query(1, max(1ll, j - d - 1), j - 1);
modify(1, j, f[j]);
}
sum[i] = sum[i - 1] + f[m];
}
int res = 1e18;
for (int l = 1, r = k; r <= n; ++ l, ++ r ) res = min(res, sum[r] - sum[l - 1]);
fout << res << '\n';
return;
}
signed main() {
int Testcases = 1;
fin >> Testcases;
while (Testcases -- ) Luogu_UID_748509();
return 0;
}
CF1945D Seraphim the Owl
有
个人站成一排,最开始第 个人在位置 上。 你是第
个人。除你之外,每个人都有两个属性 。 每次操作时,假如你在位置
上,那么你需要选择一个位置 并和位置 的人交换位置。代价为 。 求若你最终移动到的位置小于等于
,总代价最小是多少。
假如我们可以求出
我们可以画图模拟一下跟前面人交换位置的过程:
那么答案为蓝色框起的数之和
可以发现,若某个人
每个人是否选择和你交换是你可以选择的,所以对于每个人,我们看两种方式的代价
回到我们求解
int n, k, a[N], b[N], suf[N], p[N];
void Luogu_UID_748509() {
fin >> n >> k;
for (int i = 1; i <= n; ++ i ) fin >> a[i];
for (int i = 1; i <= n; ++ i ) fin >> b[i];
a[n + 1] = b[n + 1] = 0;
suf[n + 1] = p[n + 1] = 0;
for (int i = n; i; -- i ) {
suf[i] = suf[i + 1] + min(a[i], b[i]);
p[i] = suf[i + 1] + a[i];
}
fout << *min_element(p + 1, p + k + 1) << '\n';
return;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现