题目:[[2024.10.17 题目]]
## 语言
有一种新的语言,这种语言有 $26$ 个单次分别对应 $\texttt{a}$ 到 $\texttt{z}$。其中,第 $i$ 个字符词性为第 $a_i$ 类。第 $1\sim 7$ 类分别为:A, N, A/N, V, A/V, N/V, A/N/V。一个合法的句子为名词词组+动词+名词词组。名词词组可以由一个名词(N)、一个形容词(V)加一个名词词组、两个名词词组组成。现在给定字符序列 $S$,判断 $S$ 能否组成一个合法的句子。
---
签到题。根据题意,并结合学习英语的经验,不难发现只有 XX...N V XX...N 的形式才能组成一个合法的句子,其中 X 既可以是形容词 A 也可以是名词 N。因此我们枚举 V 的位置,然后对于两边做前/后缀逻辑与并特判即可。
```cpp
#include <fstream>
#include <string>
using namespace std;
const int kMaxN = 1e5 + 5;
ifstream cin("language.in");
ofstream cout("language.out");
int w[kMaxN], pre[kMaxN], suf[kMaxN], t, n, ans;
string s;
int main() {
cin.tie(0)->sync_with_stdio(0);
for (cin >> t; t; t--) {
for (int i = 'a'; i <= 'z'; i++) {
cin >> w[i];
}
cin >> s, ans = 0;
n = s.size();
s = ' ' + s;
pre[0] = 1;
for (int i = 1; i <= n; i++) {
pre[i] = pre[i - 1] && (w[s[i]] != 4);
}
suf[n + 1] = 1;
for (int i = n; i >= 1; i--) {
suf[i] = suf[i + 1] && (w[s[i]] != 4);
}
for (int i = 2; i < n && !ans; i++) {
ans = w[s[i]] >= 4 && // 自己是动词
w[s[i - 1]] != 1 && w[s[n]] != 1 && // 左边和右边最后一个是名词
pre[i - 1] && suf[i + 1]; // 名词词组
}
cout << (ans ? "Yes" : "No") << '\n';
}
return 0;
}
```
## 色球
有 $n$ 种颜色的小球,每种颜色有无限个。还有 $n$ 个球桶,每个球桶能够容下无限多的小球。一开始的球桶都是空的,有 $m$ 次操作,每次操作都是以下三种的任意一种:
- 把 $x$ 个颜色为 $y$ 的彩色小球放到第 $z$ 个桶的最上面;
- 把嘴上面的 $x$ 个小球从第 $z$ 个桶里面拿出来,并输出最后拿出来的球的颜色。保证第 $z$ 个桶里面的球数不小于 $x$ 个;
- 把第 $u$ 个桶里面的小球依次从顶部拿出并放入第 $v$ 个桶内。
---
由于颜色数量最多只有 $m$ 种,且每种颜色的球数很多,不难考虑以颜色为单位进行处理。可以想到 $\mathcal O(m^2)$ 的暴力:对于每一个桶都开一个 [[vector]],加入新的球 $\mathcal O(1)$,弹出球总共 $\mathcal O(m)$ 均摊 $\mathcal O(1)$,只有移动球的时间复杂度会达到 $\mathcal O(m)$,这将使我们超时。
收到启发式合并的影响,我们不如思考一下对于第三种操作怎么使用启发式合并。模拟可以得到,将小的合并到大的顺序会反转,因此我们还需要额外的变量来记录合并后是否反转,那么合并又要进行四种方式的特判了,过于复杂。
由于时间复杂度的瓶颈主要在第三种操作上面,因此考虑如何优化第三种操作的时间复杂度就成了刚需。在脑海中经过短暂思考,容易想到有一种冷门数据结构叫做「链表」。链表同样支持一二操作的 $\mathcal O(1)$ 时间复杂度,因为只需要进行头尾的插删,而第三种操作实际上就是将链表头连接到目标链表的链表头上。至此,本题便结束了。
**注意**:本题代码难度较高,且特别需要注意细节。好渴鹅就是因为一个小错误调试了两个小时半。(代码是删掉了文明用语的文明绿色版,调试给我调红温了)
```cpp
#include <fstream>
#include <string>
using namespace std;
using LL = long long;
const LL kMaxN = 2e5 + 5;
ifstream cin("ball.in");
ofstream cout("ball.out");
struct Node {
LL color, count, nxt, prv;
} lst[kMaxN];
LL head[kMaxN], tail[kMaxN], n, m, c;
string s;
void fuckedAdd(LL x, LL y, LL z) {
lst[++c].color = y, lst[c].count = x;
lst[c].prv = tail[z];
if (tail[z]) {
(lst[tail[z]].prv ? lst[tail[z]].nxt : lst[tail[z]].prv) = c;
} else {
head[z] = c;
}
tail[z] = c;
}
void fuckedDelete(LL shit) {
LL p;
if (lst[tail[shit]].prv) {
p = lst[tail[shit]].prv;
} else {
p = lst[tail[shit]].nxt;
}
if (p) {
(lst[p].prv == tail[shit] && (lst[p].prv = 0, 1)) || (lst[p].nxt = 0);
}
tail[shit] = p;
}
void nodeUGetMarriedWithFuckedNodeVWhoIsYourMother(LL x, LL y) {
if (head[y]) {
lst[tail[x]].prv ? lst[tail[x]].nxt = tail[y] : lst[tail[x]].prv = tail[y];
lst[tail[y]].prv ? lst[tail[y]].nxt = tail[x] : lst[tail[y]].prv = tail[x];
} else {
head[y] = tail[x];
}
tail[y] = head[x];
head[x] = tail[x] = 0;
}
int main() {
cin.tie(0)->sync_with_stdio(0);
cin >> n >> m;
for (LL x, y, z; m; m--) {
cin >> s >> x >> y;
if (s == "push") {
cin >> z;
fuckedAdd(x, y, z);
} else if (s == "pop") {
while (x > lst[tail[y]].count) {
x -= lst[tail[y]].count;
fuckedDelete(y);
}
lst[tail[y]].count -= x;
cout << lst[tail[y]].color << '\n';
} else if (s == "put") {
if (!tail[x]) {
continue;
}
nodeUGetMarriedWithFuckedNodeVWhoIsYourMother(x, y);
} else {
cout << "Fuck your mother!" << endl;
}
}
return 0;
}
```
## 斐波
令 $fib(n)=\begin{cases}0&\text{if }n=0\\1&\text{if }n=1\\ fib(n-1)+fib(n-2)&\text{else}\end{cases}$。假设 $S$ 为可重集 $\{s_1,s_2,\cdots,s_{|s|}\}$,则 ${} f(S) {}$ 定义为 $f(S)=\sum\limits_{T\subseteq S}\left[fib(\sum\limits_{s\in T}s)\right]^2$。有一个数组 $a_1,a_2,\cdots,a_n$,会进行 $q$ 次操作。每次操作都是以下两种操作的一种:
- 把 $a_p$ 变为 $v$;
- 计算 $\sum\limits_{i=l}^r\sum\limits_{j=i}^rf(\{a_i,a_{i+1},a_j\})$。
对于操作 $2$,答案对 $998244353$ 取模。
---
刚调完第二题,没时间写了,文件都没有创建,$0$ 分。出题人,我爱你。
## 偶数
对于一个正整数(去掉前导 $0$),如果它在十进制下位数为偶数且前一半与后一半一致,则称这个数为“偶数”。对于一个“偶数”,牛牛可以在这个数后面继续添加数字,使它成为一个新的偶数。牛牛总是添加最少的数字获得新的“偶数”,因此添加的方式唯一。
牛牛会对于一个偶数 $u$,一直产生新的偶数,直到偶数的位数超过给定的正整数 $n$。牛牛会多次询问你这个偶数的第 $l$ 到 $r$ 为所组成的整数摸 $998244353$ 的值是多少。$T$ 组数据。
---
刚调完第二题,没时间写了,而且题目都没有完全读懂,文件都没有创建,$0$ 分。出题人,我爱你。
## 总结
- **排名**:${} 3$;
- **比赛分数**:$200/400$;
- **情况**:相比 [[2024.10.14 模拟赛]],没区别;
- **问题**:调不出就红温。