题目链接
Codeforces Round 977 (Div. 2) C2 Adjust The Presentation (Hard Version)
思路
我们令 s [ i ] s[i] s[i]表示第 i i i名成员最早上场的时间。
显然,只有当 s s s数组单调不减时才会有解。
换句话说,只有 s [ i ] ≤ s [ i + 1 ] s[i] \le s[i+1] s[i]≤s[i+1]时才有解。
因此,我们可以使用 s e t set set来动态维护有多少个 s [ i ] ≤ s [ i + 1 ] s[i] \le s[i+1] s[i]≤s[i+1],当 s e t set set的大小为 0 0 0时有解,否则无解。
代码
cpp
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 5;
const int mod = 998244353;
const int inf = 1e6;
int n, m, q;
int a[N], b[N], s[N], idx[N];
void solve()
{
cin >> n >> m >> q;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
idx[a[i]] = i;
}
map<int, set<int>> mp;
for (int i = 1; i <= m; i++)
{
cin >> b[i];
mp[b[i]].insert(i);
}
for (int i = 1; i <= n; i++)
{
if (!mp.count(a[i]))
{
mp[a[i]].insert(inf);
}
s[i] = *mp[a[i]].begin();
}
s[n + 1] = inf;
set<int> st;
for (int i = 1; i <= n; i++)
{
if (s[i] > s[i + 1])
{
st.insert(i);
}
}
if (!st.size())
{
cout << "YA" << endl;
}
else
cout << "TIDAK" << endl;
while (q--)
{
int id, t;
cin >> id >> t;
int res = idx[b[id]];
mp[b[id]].erase(mp[b[id]].find(id));
if (mp[b[id]].size())
s[res] = *(mp[b[id]].begin());
else
s[res] = inf;
if (st.count(res))
st.erase(res);
if (res > 1 && st.count(res - 1))
st.erase(res - 1);
if (s[res] > s[res + 1])
st.insert(res);
if (s[res - 1] > s[res] && res > 1)
st.insert(res - 1);
b[id] = t;
res = idx[t];
mp[t].insert(id);
s[res] = *mp[t].begin();
if (st.count(res))
st.erase(res);
if (res > 1 && st.count(res - 1))
st.erase(res - 1);
if (s[res] > s[res + 1])
st.insert(res);
if (s[res - 1] > s[res] && res > 1)
st.insert(res - 1);
if (!st.size())
{
cout << "YA" << endl;
}
else
cout << "TIDAK" << endl;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int test = 1;
cin >> test;
for (int i = 1; i <= test; i++)
{
solve();
}
return 0;
}