有数组A[N],初始时元素都为0,另外还有初始为空的集合S。依次处理以下Q组查询:给出整数x[i],如果S包含x[i],则从S中移除x[i],否则将x[i]加入S,记此时S的大小为|S|,把|S|加到集合中的每个元素i对应的A[i]中。求最终A[i]是多少。
1<=N,Q<=2E5; 1<=x[i]<=N
分析:记录每个时刻集合S的大小,设元素u在t1时刻加入集合,在t2时刻移出集合,那么[t1,t2)区间各个时刻集合的大小都要加到u对应的答案中,因此用前缀和维护集合大小。
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int N, Q;
std::cin >> N >> Q;
std::vector<i64> A(Q + 1);
for (int i = 1; i <= Q; i++) {
std::cin >> A[i];
}
std::set<i64> st;
std::vector<i64> cnt(Q + 1);
for (int i = 1; i <= Q; i++) {
if (st.count(A[i])) {
st.erase(A[i]);
} else {
st.insert(A[i]);
}
cnt[i] = st.size();
}
std::partial_sum(cnt.begin(), cnt.end(), cnt.begin());
auto sum = [&](int l, int r) {
return l <= r ? cnt[r] - cnt[l - 1] : 0;
};
std::set<int> st1;
std::vector<int> lst(Q + 1);
std::vector<i64> ans(Q + 1);
for (int i = 1; i <= Q; i++) {
if (st1.count(A[i])) {
ans[A[i]] += sum(lst[A[i]], i - 1);
st1.erase(A[i]);
} else {
st1.insert(A[i]);
lst[A[i]] = i;
}
}
for (auto i : st1) {
ans[i] += sum(lst[i], Q);
}
for (int i = 1; i <= N; i++) {
std::cout << ans[i] << " \n"[i == N];
}
}
int main() {
std::cin.tie(0)->sync_with_stdio(0);
std::cout << std::fixed << std::setprecision(10);
int t = 1;
while (t--) solve();
return 0;
}
标签:std,Set,int,Add,abc347E,vector,集合,Query,时刻
From: https://www.cnblogs.com/chenfy27/p/18453126