Day 3
Day 3
早晨
我和 zyq 很早就去吃早饭了. lyd 和 lzy 在我们两个吃完早饭后还没出来, 我俩就直接去东师了.
上午
神秘模拟赛.
T1
想了一卡车神秘贪心, 其中最接近正解的一个因为少考虑一层嵌套假了.
最后模拟退火赌出来 \(20pts\) .
T2
做 T2 的时候已经只有 \(30mins\) 了, 打了下性质 \(A\) 结果发现有 \(k = 0\) 导致挂飞.
总结
\(20\) 对我来说是一个很特殊的数字吧. 当初 CSP-S2 就是 \(20\) 分爆冷.
\(20\) 是落败, 是新生, 是不甘, 是曙光, 是过往, 是当下.
离落败, 忍不甘, 忆往昔, 亦往兮.
中午
去吃了个牛肉汉堡, 然后就回东师改题了 —— 没回酒店.
下午(改题)
T1
给你一个长度为 \(2n\) 的序列, 你需要对其进行配对, 保证所有对的差不超过 \(A\), 求差不超过 \(B\) 的最大对数.
\(A \ge B\) .
我们考虑排序后从左到右扫描, 可以证明最多有两层嵌套, 所以我们如果说发现当前值的后两位大于当前已经确定的左端点, 就把当前位置和左端点配对, 不加分.
如果说当前节点和下一位能够配对就加分. 否则, 与前面的左端点进行配对 / 选定新的左端点.
复杂度 \(\mathcal{O}(n \log n)\) .
#include <bits/stdc++.h>
using namespace std;
namespace OI {
#define int long long
#define endl "\n"
constexpr int maxn = 1e6+5;
int T, n;
int A, B, p;
int w[maxn];
int a[maxn];
bool vis[maxn];
void main() {
cin >> T >> n;
for (int i = 1; i <= 2 * n; i++) {
cin >> w[i];
}
int initT = T;
while (T--) {
cin >> p;
while (p--) {
int x, v;
cin >> x >> v;
w[x] = v;
}
memset(vis, 0, sizeof vis);
for (int i = 1; i <= 2 * n; i++)
a[i] = w[i];
sort(a + 1, a + 1 + 2 * n);
cin >> A >> B;
int ret = -1;
int ready = 0;
for (int i = 1; i <= 2 * n; i += 2)
if (a[i + 1] - a[i] > A) {
ret = -1;
goto end;
}
for (int i = 1; i <= 2 * n; i++) {
if (vis[i])
continue;
vis[i] = 1;
if (a[i + 2] - a[ready] > A)
ready = 0;
else if (a[i + 1] && a[i + 1] - a[i] <= B) {
ret++;
vis[i + 1] = 1;
}
else if (!ready)
ready = i;
else
ready = 0;
}
end:
cout << ret << endl;
}
}
#undef int
#undef endl
}
int main() {
freopen("dove.in", "r", stdin);
freopen("dove.out", "w", stdout);
cin.tie(0), cout.tie(0);
ios::sync_with_stdio(0);
OI::main();
return 0;
}
此恨绵绵无绝期
T2
给你一个 \(n \times m\) 的区块和若干个障碍物, 求最大的 \(x \times x\) 能够扫描整个区块.
注意到这个有单调性.
然后我们可以进行二分, \(check\) 函数是 \(BFS\) .
我们要找到一个可以放下你的方块的位置开始 \(BFS\) .
使用二维前缀和 + 差分, 复杂度 \(\mathcal{O}(S \log S)\) .
有点像我以前讲过的一道推箱子的题. 忘了是哪个了, CF 上的圆方树 + BFS.
下午(DS)
T3
这时候发现 T3 没有人切, 寻思抢首切.
给你一个带修的括号序列, 你可以在上面向左右移动, 你的步伐会被记录下来, 问你能不能从左到右走出一个合法括号序列.
我们可以用 std::set 去维护每个连续段的位置, 如果:
- 奇数 - 必定不可行
)开头 /(结尾 - 必定不可行- 没有连续段 - 可行
- 有两种连续段且
(在左)在右 - 可行
这是显然对, 因为如果有两种连续段你可以来回走配平.
然后你就切了.
#include <bits/stdc++.h>
using namespace std;
namespace OI {
#define int long long
#define endl "\n"
constexpr int maxn = 2e5+5;
int n, q;
string str;
set<int> L, R;
void main() {
cin >> n >> q;
cin >> str;
str = ' ' + str;
for (int i = 1; i < n; i++)
if (str[i] == str[i + 1])
if (str[i] == '(')
L.insert(i);
else
R.insert(i);
while (q--) {
int x;
cin >> x;
if (n & 1) {
cout << "NO" << endl;
continue;
}
if (str[x] == '(') {
str[x] = ')';
if (x > 1)
if (str[x - 1] == '(')
L.erase(x - 1);
else
R.insert(x - 1);
if (x < n)
if (L.count(x))
L.erase(x);
else
R.insert(x);
} else {
str[x] = '(';
if (x > 1)
if (str[x - 1] == ')')
R.erase(x - 1);
else
L.insert(x - 1);
if (x < n)
if (R.count(x))
R.erase(x);
else
L.insert(x);
}
if (str[1] == ')' || str[n] == '(')
cout << "NO" << endl;
else if (L.empty() && R.empty())
cout << "YES" << endl;
else if (L.empty() || R.empty())
cout << "NO" << endl;
else if ((*L.begin() < *R.begin()) && (*L.rbegin() < *R.rbegin()))
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}
#undef int
#undef endl
}
int main() {
cin.tie(0), cout.tie(0);
ios::sync_with_stdio(0);
OI::main();
return 0;
}
说实话这题有点史.
CodeForces 忙
首切被抢了.
T1
给你若干次操作, 每次往数组里加入两个数字. 返回数组中位数.
告诉你中位数序列, 问你中位数序列是否可能出现.
很简单啊, 每次把当前的 \(b_i\) 和 \(b_{i - 1}\) 进行判断, 看他们在 \(set\) 里是否相邻就好了.
#include <bits/stdc++.h>
using namespace std;
namespace OI {
#define int long long
#define endl "\n"
constexpr int maxn = 2e5+5;
int T, n;
int b[maxn];
set<int> st;
void main() {
cin >> T;
while (T--) {
cin >> n;
st.clear();
bool flag = 0;
for (int i = 1; i <= n; i++) {
cin >> b[i];
if (flag)
continue;
st.insert(b[i]);
if (i > 1) {
if (b[i] > b[i - 1]) {
if (st.upper_bound(b[i - 1]) != st.lower_bound(b[i])) {
cout << "NO" << endl;
flag = 1;
}
} else if (b[i - 1] > b[i]) {
if (st.lower_bound(b[i - 1]) != st.upper_bound(b[i])) {
cout << "NO" << endl;
flag = 1;
}
}
}
}
if (!flag)
cout << "YES" << endl;
}
}
#undef int
#undef endl
}
int main() {
cin.tie(0), cout.tie(0);
ios::sync_with_stdio(0);
OI::main();
return 0;
}
T2
没写完, 写了个线段树 MLE 了.
晚上
今日无晚自习.
回宾馆之后开始打麻将.
多次尝试做国士无双无果, 和的基本都是小牌.

(三家做国, 最后我放弃做过和了)

(神秘流局, zyq 听国和红中结果两家一人一对)
诈骗时刻!
(此时我上听了,和西风七小对)
zyq: 我是不是该防守啊, 航空兵不是就喜欢和那些奇奇怪怪的东西么
hkb: 你就打呗, 什么安牌字牌就往外打啊
zyq: 万一你和字牌呢?
hkb: 谁家好人和字牌啊?
lyd: 还真不一定, 偶尔会有人和字牌
zyq: 那你不和字牌啊, 那我打了(西风)
hkb: \(\textcolor{red}{他信了!!!}\)
(无图)
最后一把吃 \(1st\) 了.
晚上回宿舍的时候把脑袋磕到了, 流了点脓血.
事件 —— 水淹七军
由于我和 zyq 生活习惯不同, 我把花洒挂在上面的时候花洒的朝向是浴室外面.
zyq 为了提前预热水温, 在穿着衣服的时候就给花洒打开了, 然后他湿身了.
EEEEEEEE
神秘对话
zyq: 你要不再把花洒冲着外面穿衣服呢?
hkb: 有何不敢!
(我给花洒打开了, 然后衣服右边全湿了)
半夜


后来在和别人下飞行棋, 输完了.
怎么会有人连续两次扔三个六啊!怎么是我!
嗯。最有喜感的一天.

浙公网安备 33010602011771号