题解 QOJ1963【[Seoul21J] Squid Game】/ BC2401B【空当接球】
题目描述
有
QOJ1963:
BC2401B:
solution n=3
不妨设
你观察,如果
我们观察最小值,从
我们提出以下算法,倒出一桶
既然可以使最小值从
solution n<=3e5(黄队做法)
将序列从小到大排序,如果相邻两项的商比较小,小到
solution n<=3e5(题解)
从小到大枚举
对前一部分的次数分析:定义势能为
code
黄队做法实现
#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#define debug(...) fprintf(stderr, ##__VA_ARGS__)
#else
#define endl "\n"
#define debug(...) void(0)
#endif
using LL = long long;
mt19937 rng{random_device{}()};
struct node {
LL x;
int id;
operator LL() const { return x; }
};
vector<pair<int, int>> ans;
void perf(node& lhs, node& rhs) {
if (lhs < rhs) swap(lhs, rhs);
assert(lhs.id != rhs.id);
lhs.x -= rhs.x, rhs.x <<= 1;
ans.emplace_back(lhs.id, rhs.id);
if (ans.size() >= (int)8.5e5) exit(0);
}
void printans() {
cout << ans.size() << endl;
for (auto&& e : ans) cout << e.first << " " << e.second << endl;
}
int n;
LL m;
void solve(vector<node> vec) {
shuffle(vec.begin(), vec.end(), rng);
auto choice = [&]() {
swap(vec[rng() % vec.size()], vec.back());
auto ret = vec.back();
vec.pop_back();
return ret;
};
while (vec.size() > 2) {
vector<node> tmp{choice(), choice(), choice()};
auto &a = tmp[0], &b = tmp[1], &c = tmp[2];
while (a && b && c) {
sort(tmp.begin(), tmp.end());
if (b == c) {
perf(b, c);
} else if (a) {
auto k = b / a + (b % a > a / 2);
for (LL j = 1; j <= k; j <<= 1) perf(j & k ? b : c, a);
}
}
for (auto e : {a, b, c}) if (e) vec.push_back(e);
}
}
node a[300010];
int main() {
#ifndef LOCAL
#ifndef NF
freopen("ball.in", "r", stdin);
freopen("ball.out", "w", stdout);
#endif
cin.tie(nullptr)->sync_with_stdio(false);
#endif
atexit(printans);
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i].x, a[i].id = i;
for (int t = 1; t <= 200; t++) {
sort(a + 1, a + n + 1);
for (int i = 1; i < n; i++) if (a[i] && (double)a[i + 1] / a[i] < 1.6) perf(a[i + 1], a[i]);
}
solve(vector<node>(a + 1, a + n + 1));
return 0;
}
题解做法实现
#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#define debug(...) fprintf(stderr, ##__VA_ARGS__)
#else
#define endl "\n"
#define debug(...) void(0)
#endif
using LL = long long;
mt19937 rng{random_device{}()};
struct node {
LL x;
int id;
operator LL() const { return x; }
};
vector<pair<int, int>> ans;
void perf(node& lhs, node& rhs) {
if (lhs < rhs) swap(lhs, rhs);
assert(lhs.id != rhs.id);
lhs.x -= rhs.x, rhs.x <<= 1;
ans.emplace_back(lhs.id, rhs.id);
if (ans.size() >= (int)8.5e5) exit(0);
}
void printans() {
cout << ans.size() << endl;
for (auto&& e : ans) cout << e.first << " " << e.second << endl;
}
int n;
LL m;
void solve(vector<node> vec) {
shuffle(vec.begin(), vec.end(), rng);
auto choice = [&]() {
swap(vec[rng() % vec.size()], vec.back());
auto ret = vec.back();
vec.pop_back();
return ret;
};
while (vec.size() > 2) {
vector<node> tmp{choice(), choice(), choice()};
auto &a = tmp[0], &b = tmp[1], &c = tmp[2];
while (a && b && c) {
sort(tmp.begin(), tmp.end());
if (b == c) {
perf(b, c);
} else if (a) {
auto k = b / a;
for (LL j = 1; j <= k; j <<= 1) perf(j & k ? b : c, a);
}
}
for (auto e : {a, b, c}) if (e) vec.push_back(e);
}
}
node a[300010];
int main() {
#ifndef LOCAL
#ifndef NF
freopen("ball.in", "r", stdin);
freopen("ball.out", "w", stdout);
#endif
cin.tie(nullptr)->sync_with_stdio(false);
#endif
atexit(printans);
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i].x, a[i].id = i;
for (int t = 1; t <= 200; t++) {
sort(a + 1, a + n + 1);
for (int i = 1; i < n; i++) if (a[i] && (double)a[i + 1] / a[i] < 1.6) perf(a[i + 1], a[i]);
}
solve(vector<node>(a + 1, a + n + 1));
return 0;
}
本文来自博客园,作者:caijianhong,转载请注明原文链接:https://www.cnblogs.com/caijianhong/p/18432315/solution-QOJ1963
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2023-09-25 题解 T378010 / SS241121C【Soso 的排列】
2023-09-25 题解 AtCoder Beginner Contest 268 A~H