C2. Adjust The Presentation (Hard Version)
This is the hard version of the problem. In the two versions, the constraints on $q$ and the time limit are different. In this version, $0 \leq q \leq 2 \cdot 10^5$. You can make hacks only if all the versions of the problem are solved.
A team consisting of $n$ members, numbered from $1$ to $n$, is set to present a slide show at a large meeting. The slide show contains $m$ slides.
There is an array $a$ of length $n$. Initially, the members are standing in a line in the order of $a_1, a_2, \ldots, a_n$ from front to back. The slide show will be presented in order from slide $1$ to slide $m$. Each section will be presented by the member at the front of the line. After each slide is presented, you can move the member at the front of the line to any position in the lineup (without changing the order of the rest of the members). For example, suppose the line of members is $[\color{red}{3},1,2,4]$. After member $3$ presents the current slide, you can change the line of members into either $[\color{red}{3},1,2,4]$, $[1,\color{red}{3},2,4]$, $[1,2,\color{red}{3},4]$ or $[1,2,4,\color{red}{3}]$.
There is also an array $b$ of length $m$. The slide show is considered good if it is possible to make member $b_i$ present slide $i$ for all $i$ from $1$ to $m$ under these constraints.
However, your annoying boss wants to make $q$ updates to the array $b$. In the $i$-th update, he will choose a slide $s_i$ and a member $t_i$ and set $b_{s_i} := t_i$. Note that these updates are persistent, that is changes made to the array $b$ will apply when processing future updates.
For each of the $q+1$ states of array $b$, the initial state and after each of the $q$ updates, determine if the slideshow is good.
Input
Each test contains multiple test cases. The first line contains the number of test cases $t$ ($1 \le t \le 10^4$). The description of the test cases follows.
The first line of each test case contains three integers $n$, $m$ and $q$ ($1 \le n, m \le 2 \cdot 10^5$; $0 \leq q \leq 2 \cdot 10^5$) — the number of members and the number of sections.
The second line of each test case contains $n$ integers $a_1,a_2,\ldots,a_n$ ($1 \le a_i \le n$) — the initial order of the members from front to back. It is guaranteed that each integer from $1$ to $n$ appears exactly once in $a$.
The third line of each test case contains $m$ integers $b_1, b_2, \ldots, b_m$ ($1 \le b_i \le n$) — the members who should present each section.
Each of the next $q$ lines contains two integers $s_i$ and $t_i$ ($1 \le s_i \le m$, $1 \le t_i \le n$) — parameters of an update.
It is guaranteed that the sum of $n$, the sum of $m$ and the sum of $q$ over all test cases do not exceed $2 \cdot 10^5$ respectively.
Output
For each test case, output $q+1$ lines corresponding to the $q+1$ states of the array $b$. Output "YA" if the slide show is good, and "TIDAK" otherwise.
You can output the answer in any case (upper or lower). For example, the strings "yA", "Ya", "ya", and "YA" will be recognized as positive responses.
Example
Input
3
4 2 2
1 2 3 4
1 1
1 2
1 1
3 6 2
1 2 3
1 1 2 3 3 2
3 3
2 2
4 6 2
3 1 4 2
3 1 1 2 3 4
3 4
4 2
Output
YA
TIDAK
YA
YA
TIDAK
YA
TIDAK
YA
YA
Note
For the first test case, you do not need to move the members as both slides are presented by member $1$, who is already at the front of the line. After that, set $b_1 := 2$, now slide $1$ must be presented by member $2$ which is impossible as member $1$ will present slide $1$ first. Then, set $b_1 = 1$, the $b$ is the same as the initial $b$, making a good presentation possible.
解题思路
当 $b$ 固定后,要判断其是否是好的,只需从 $b$ 中依次把第一次出现的数选出来,并判断所构成的序列 $c$ 是否等于 $a$ 的前缀即可。例如有 $a = [2, 4, 1, 3]$,$b = [2, 2, 4, 2, 4, 1, 4]$,依次选出第一次出现的数就是 $c = [2, 4, 1]$,等于 $a$ 的前缀,说明是好的。如果 $c$ 不是 $a$ 的前缀,说明必定存在最小的位置 $i$ 使得 $a_i \ne c_i$,说明在 $a$ 中 $a_i$ 比 $c_i$ 先出现。又因为 $c_1 \sim c_{i-1}$ 中不存在 $a_i$,因此 $a_i$ 必定会与 $b$ 中某个位置发生失配。否则 $c$ 是 $a$ 的前缀,容易知道存在构造方案使得 $b$ 是好的。
由于涉及到修改,容易想到维护 $c$,每次修改相当于令 $c$ 中某一段循环左移或右移一个单位,非常难维护而且还要判断是否为 $a$ 的前缀,一开始死磕这种方法做不出来。参考了一下别人的代码,发现实际上维护的是每个值第一次出现的位置。定义 $f(i)$ 表示在 $b$ 中值 $a_i$ 第一次出现的位置(不存在则设为 $+\infty$),如果 $c$ 是 $a$ 的前缀,说明在 $b$ 中一定是先出现 $a_1$,再出现 $a_2$,再出现 $a_3$ 以此类推,这等价于 $f(1) < f(2) < \cdots < f(n)$。所以可以用一个变量 $\text{cnt}$ 统计不满足 $f(i) < f(i+1)$ 的数目,如果 $\text{cnt} = 0$ 说明 $b$ 是好的,否则不好。
给 $1 \sim n$ 每个值开一个 std::set
存 $b$ 中出现的位置。当将 $b_x$ 修改成 $t$ 时,因为 $f(p_{b_x})$ 和 $f(p_{t})$ 会改变,其中 $p_x$ 表示 $a$ 中值 $x$ 的下标,因此受影响的只有 $f(p_{b_x} - 1)$,$f(p_{b_x})$,$f(p_{b_x} + 1)$ 之间的关系,以及 $f(p_{t} - 1)$,$f(p_{t})$,$f(p_{t} + 1)$ 之间的关系。在将 $b_x$ 改成 $t$ 的过程中相应地更新 $\text{cnt}$ 即可,同时还要维护 $b_x$ 和 $t$ 对应的 std::set
。
AC 代码如下,时间复杂度为 $O(q\log{n})$:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 5;
int n, m, k;
int a[N], b[N], p[N];
set<int> st[N];
int f[N], cnt;
void upd(int x, int op) {
if (p[b[x]] - 1 > 0) cnt -= f[p[b[x]] - 1] > f[p[b[x]]];
if (p[b[x]] + 1 <= n) cnt -= f[p[b[x]]] > f[p[b[x]] + 1];
if (op) st[b[x]].insert(x);
else st[b[x]].erase(x);
f[p[b[x]]] = *st[b[x]].begin();
if (p[b[x]] - 1 > 0) cnt += f[p[b[x]] - 1] > f[p[b[x]]];
if (p[b[x]] + 1 <= n) cnt += f[p[b[x]]] > f[p[b[x]] + 1];
}
void solve() {
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
p[a[i]] = i;
}
for (int i = 1; i <= n; i++) {
st[i].clear();
st[i].insert(m + 1);
}
for (int i = 1; i <= m; i++) {
cin >> b[i];
st[b[i]].insert(i);
}
for (int i = 1; i <= n; i++) {
f[i] = *st[a[i]].begin();
}
cnt = 0;
for (int i = 1; i < n; i++) {
cnt += f[i] > f[i + 1];
}
cout << (cnt ? "TIDAK" : "YA") << '\n';
while (k--) {
int x, y;
cin >> x >> y;
upd(x, 0);
b[x] = y;
upd(x, 1);
cout << (cnt ? "TIDAK" : "YA") << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
标签:le,slide,Adjust,members,each,test,C2,line,Presentation
From: https://www.cnblogs.com/onlyblues/p/18449401