最终测试
名选手正在参加比赛,第 名选手作答了两道题,分值为 与 ,每道题有 的正确概率,求每个选手最终排名的期望,误差不超过 。选手的排名定义为比他分数高的人数 的值。
本题 ,很显然出题人想要我们使用 或 解法。每个人有两道题,每道题有两种可能的状态,因此不难想到将一个人拆成四份(即四种不同的总分),这个人的期望就是每一份的期望的平均值。
接下来考虑怎么求每一份的期望。既然别人也可以有四份,那么我们就把别人的四份总分 对应在数轴上的点计数器 ,然后大于每一份的值的点的数量就是排名的总和,除以 得到每一份的期望。然后再除以 即可得到每个人的期望。由于第一名排名为 ,因此答案需要额外 。
该算法的时间复杂度为 。不难想到使用树状数组来维护数轴上的点的数量(连离散化都不需要),先把每个人的每一份都加进去,然后对于每一个人 将 的 份从树状数组中删除,再根据上面的过程模拟即可。时间复杂度 。
#include <fstream>
#include <iomanip>
using namespace std;
using LL = long long;
const LL kMaxN = 1e5 + 5;
ifstream cin("test.in");
ofstream cout("test.out");
LL a[kMaxN][3], t[kMaxN], n;
void modify(LL x, LL y) {
for (x++; x <= 1e5; x += x & -x) {
t[x] += y;
}
}
LL query(LL x) {
LL res = 0;
for (x++; x; x -= x & -x) {
res += t[x];
}
return res;
}
LL get(LL x) {
return query(1e5) - query(x);
}
void fuck(LL a, LL b, LL v) {
modify(0, v);
modify(a, v);
modify(b, v);
modify(a + b, v);
}
int main() {
cin.tie(0)->sync_with_stdio(0);
cin >> n;
for (LL i = 1; i <= n; i++) {
cin >> a[i][1] >> a[i][2];
fuck(a[i][1], a[i][2], 1);
}
for (LL i = 1; i <= n; i++) {
fuck(a[i][1], a[i][2], -1);
cout << fixed << setprecision(6) << (get(0) + get(a[i][1]) + get(a[i][2]) + get(a[i][1] + a[i][2])) / 16.0 << '\n';
fuck(a[i][1], a[i][2], 1);
}
return 0;
}空间跳跃
给定正整数 ,初始有整数 ,可以做以下三种操作:
- 将 改变为 ;
- 若 ,可以将 改为 ;
- 若 ,则可以将 改为 。
次询问,每次询问给出目的地 ,求变换方案使得 最终能够变换为 。输出方案,变换次数不能超过 次。
仔细观察操作 和操作 ,不难发现它正好为冰雹猜想的翻转版本。(冰雹猜想:对于任意正整数 ,若 为偶数则 ,否则 。在有限次操作内, 最终变为 )那么,对于任意 ,我们直接使用冰雹猜想即可;对于 ,我们让 也可以。
现在最大的问题就是如何使得一个负数 快速变为非负整数,因为冰雹猜想并不能在负数下成立,会在某几个数字间不断循环。观察第二种操作,在看看数据范围,发现 ,这就代表着我们只需要变换到 即可直接使用第二种操作将其变为非负整数。根据验证,任意 都可以在不超过五百次操作 和操作 下变为 。此时,题目已经解出来了,但是我们来考虑下负数情况下冰雹猜想的性质。
根据模拟,可以发现 时 会在 中循环,这也是为什么大多数题解都对这几个数进行了特判,如果满足则循环使用第二种性质,但是似乎没有题解指出这么做的意义何在。
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
using LL = long long;
ifstream cin("jump.in");
ofstream cout("jump.out");
LL q, d, l, x;
vector<LL> ans;
int main() {
cin.tie(0)->sync_with_stdio(0);
for (cin >> q >> d >> l; q; q--) {
cin >> x;
ans.clear();
if (x < 1) {
// Shabi Bingbao Caixiang
while (x < -1e3) { // 亦可设置成其它较大负数,如 -114
ans.push_back(x);
x = x % 2 ? x * 3 + 1 : x / 2;
}
// Zhijie Jia
while (x < 1) {
ans.push_back(x);
x += d;
}
}
// Shabi Bingbao Caixiang
while (x != 1) {
ans.push_back(x);
x = x % 2 ? x * 3 + 1 : x / 2;
}
cout << ans.size() << ' ';
ans.push_back(x);
reverse(ans.begin(), ans.end());
for (LL i : ans) {
cout << i << ' ';
}
cout << '\n';
}
return 0;
}
快速访问
有 个结点的树,结点编号为 ,第 条边连接 与 。求对于 , 的值,其中 , 为 到 的简单路径经过的边的数量。
采用暴力。通过 dfs 预处理+倍增方法快速求出任意两点的最近公共祖先,在配合题意模拟并计算满足条件的两点长度和。时间复杂度 ,可以通过 Tarjan 的离线算法达到 。得到 分。
门童
牛牛去当志愿者。大厅沙发和大门距离为 个单位,牛牛在每秒可以做以下事:
- 站在门口不动,开心度每秒减少 ;
- 从门口走向沙发一个单位,开心度每秒减少 ;
- 从沙发走向门口一个单位,开心度每秒减少 ;
- 在沙发上摸鱼,开心度每秒增加 。
有 名选手需要牛牛接待,第 名选手会在第 秒到达大门,它的耐心值为 ,友善值为 ,牛牛必须要在任意时刻 接待,接待瞬间完成,开心值会在接待的瞬间上升 。
牛牛在第 秒站在门口,开心度为 。求牛牛在工作完成的时刻,开心度可以达到的最大值。
没有完全看懂题目,代码都没有写,出题人我喜欢你。
后记:发现模拟牛牛一直在大门口可以得到 分。天地人,你我他,数据人我___你___。
总结
- 排名:;
- 比赛分数:;
- 情况:相比 2024.10.14 模拟赛,较好;
- 问题:容易红温。