题意:https://codeforces.com/contest/1847/problem/D
思路:首先字典序越大代表1都尽量放前面。我们对于每个位置找他在最后串中第一次出现的位置,当前字典序最大显然就是把当前的1全部放在前面,或者塞满了。那么我们的交换次数就是前当前1的个数的位置有多少个0,树状数组维护即可。
/*keep on going and never give up*/
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<set>
using namespace std;
#define int long long
typedef pair<int, int> pii;
#define lowbit(x) x&(-x)
#define endl '\n'
#define wk is zqx ta die
int id[200005];
int l[200005];
int r[200005];
int f[200005];
int n, m, q;
void add(int x, int y) {
while (x <= n) {
f[x] += y;
x += lowbit(x);
}
}
int query(int x) {
int res = 0;
while (x) {
res += f[x];
x -= lowbit(x);
}
return res;
}
signed main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> q;
string s;
cin >> s;
s = '!' + s;
set<int> st;
for (int i = 1; i <= m; i++) {
cin >> l[i] >> r[i];
}
for (int i = 1; i <= n; i++) {
st.insert(i);
}
int tot = 0;
for (int i = 1; i <= m; i++) {
auto it = st.lower_bound(l[i]);
while (it != st.end() && *it <= r[i]) {
int u = *it;
it++;
id[u] = ++tot;
st.erase(u);
}
}
int li = tot;
int cnt = 0;
for (int i : st) {
id[i] = ++tot;
}
for (int i = 1; i <= n; i++) {
if (s[i] == '1') {
cnt++;
} else {
add(id[i], 1);
}
}
while (q--) {
int x;
cin >> x;
if (s[x] == '1') {
cnt--;
add(id[x], 1);
s[x] = '0';
int sum = min(li, cnt);
int ans = query(sum);
cout << ans << endl;
} else {
cnt++;
add(id[x], -1);
s[x] = '1';
int sum = min(li, cnt);
int ans = query(sum);
cout << ans << endl;
}
}
return 0;
}