VP Educational Codeforces Round 10
A. Gabriel and Caterpillar
题意:一个毛毛虫要从
这题读题给我读傻了,题目说一开始是从下午两点开始观察的,我以为它也要到某天的下午两点后到
其实就是个模拟,只要注意一开始的一天只有8小时往上爬,然后特判一下无解的情况就行了。
点击查看代码
void solve() {
i64 x, y, a, b;
std::cin >> x >> y >> a >> b;
if (x + a * 8 >= y) {
std::cout << 0 << "\n";
return;
}
x = x + a * 8 - b * 12;
if (x + 12 * a < y && a <= b) {
std::cout << -1 << "\n";
return;
}
int ans = 1;
x += 12 * a;
while (x < y) {
x -= 12 * b;
++ ans;
x += 12 * a;
}
std::cout << ans << "\n";
}
B. z-sort
题意:给你一个数组,你要重新排列它,使得偶数位置上的数大于等于左边的数,奇数位置上的数小于等于左边的数。
排序后拿前半部分给奇数位置,后半部分给偶数位置。
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
std::sort(a.begin(), a.end());
for (int i = 0, j = 0, k = (n + 1) / 2; i < n; ++ i) {
if (i & 1) {
std::cout << a[k] << " ";
k += 1;
} else {
std::cout << a[j] << " ";
j += 1;
}
}
std::cout << "\n";
}
C. Foe Pairs
题意:给你一个排列,和若干对限制,如果一个区间里有两个数在这些限制里,就不能选,求能选多少区间。
给每个数几下配对的数,然后从前往后枚举,记录每个数上一次出现的地方,那么和当前位置上的数匹配的数出现的位置的最大值就是我们能选的左边界。
点击查看代码
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
std::vector<std::set<int>> s(n + 1);
for (int i = 0; i < m; ++ i) {
int x, y;
std::cin >> x >> y;
s[x].insert(y);
s[y].insert(x);
}
i64 ans = 0;
int last = -1;
std::vector<int> pre(n + 1, -1);
for (int i = 0; i < n; ++ i) {
for (auto & x : s[a[i]]) {
last = std::max(last, pre[x]);
}
ans += i - last;
pre[a[i]] = i;
}
std::cout << ans << "\n";
}
D. Nested Segments
题意:给
先离散化,然后按右端点排序,那么我们按顺序枚举的
点击查看代码
template <class T>
struct Fenwick {
int n;
std::vector<T> tr;
Fenwick(int _n) {
init(_n);
}
void init(int _n) {
n = _n;
tr.assign(_n + 1, T{});
}
void add(int x, const T &v) {
for (int i = x; i <= n; i += i & -i) {
tr[i] = tr[i] + v;
}
}
T query(int x) {
T res{};
for (int i = x; i; i -= i & -i) {
res = res + tr[i];
}
return res;
}
T sum(int l, int r) {
return query(r) - query(l - 1);
}
};
void solve() {
int n;
std::cin >> n;
std::vector<std::array<int, 3>> a(n);
std::vector<int> b;
for (int i = 0; i < n; ++ i) {
int l, r;
std::cin >> l >> r;
a[i] = {l, r, i};
b.push_back(l);
b.push_back(r);
}
std::sort(b.begin(), b.end());
b.erase(std::unique(b.begin(), b.end()), b.end());
auto get = [&](int x) -> int {
return std::lower_bound(b.begin(), b.end(), x) - b.begin() + 1;
};
int m = b.size();
for (auto & [l, r, id] : a) {
l = get(l);
r = get(r);
}
std::sort(a.begin(), a.end(), [&](std::array<int, 3> & a, std::array<int, 3> & b) {
return a[1] < b[1];
});
std::vector<int> ans(n);
Fenwick<int> tr(m + 1);
for (auto & [l, r, id] : a) {
ans[id] = tr.sum(l, m);
tr.add(l, 1);
}
for (int i = 0; i < n; ++ i) {
std::cout << ans[i] << "\n";
}
}
E. Pursuit For Artifacts
题意:给你一个图,边权只有
如果两个点在一个环里,且这个环里有边的边权是1,那么就一定可以拿到这个1,那么只要在一个边联通分量里有至少一条1边,那么这个联通分量任意两个点都有满足的路径,那么考虑缩点,缩点后是一棵树,只需要看
点击查看代码
const int N = 3e5 + 5, M = 6e5 + 5;
int head[N], ver[M], next[M], w[M], tot;
int dfn[N], low[N], stk[N], top, id[N], idx, cnt;
std::vector<std::pair<int, int>> adj[N];
int f[N];
int n, m;
void add(int u, int v, int x) {
ver[tot] = v; w[tot] = x; next[tot] = head[u]; head[u] = tot ++ ;
}
void tarjan(int u, int fa) {
dfn[u] = low[u] = ++ idx;
stk[ ++ top] = u;
for (int i = head[u]; i != -1; i = next[i]) {
int v = ver[i];
if (!dfn[v]) {
tarjan(v, i);
low[u] = std::min(low[u], low[v]);
} else if ((i ^ 1) != fa) {
low[u] = std::min(low[u], dfn[v]);
}
}
if (dfn[u] <= low[u]) {
int v;
++ cnt;
do {
v = stk[top -- ];
id[v] = cnt;
} while (v != u);
}
}
int a, b;
bool dfs(int u, int s, int fa) {
s |= f[u];
if (u == b) {
return s == 1;
}
for (auto & [v, w] : adj[u]) {
if (v == fa) {
continue;
}
if (dfs(v, s | w, u)) {
return true;
}
}
return false;
}
void solve() {
std::cin >> n >> m;
memset(head, -1, sizeof head);
for (int i = 0; i < m; ++ i) {
int u, v, w;
std::cin >> u >> v >> w;
add(u, v, w);
add(v, u, w);
}
std::cin >> a >> b;
for (int i = 1; i <= n; ++ i) {
if (!dfn[i]) {
tarjan(i, -1);
}
}
for (int u = 1; u <= n; ++ u) {
for (int i = head[u]; i != -1; i = next[i]) {
int v = ver[i];
if (id[u] == id[v]) {
f[id[u]] |= w[i];
} else {
adj[id[u]].push_back({id[v], w[i]});
}
}
}
a = id[a], b = id[b];
if (dfs(a, 0, 0)) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
}
分类:
codeforces
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析