题解:AT_abc347_e [ABC347E] Set Add Query
赛时离 只差一点。最可惜的一集。
思路
显然不能每一次都给现在在集合中的元素加,这样一定会 。
不妨模仿 ,进行离线操作,即( 为当前第 次操作,第 次集合元素为 个):
- 元素进入集合时,进行标记,即 。
- 元素离开集合时,答案增加,。
注意:当 元素离开的那一次,它是不会被计算的!
就做完了。
代码实现
#include<bits/stdc++.h>
using namespace std;
int a[200005],n,q;
bool f[200005];
int sum[200005],ci[200005],last[200005];
long long ans[200005]={0},sumsum[200005]={0};
int main(){
cin>>n>>q;
// cout<<ans[2]<<endl;
for(int i=1;i<=q;i++){
cin>>a[i];
f[a[i]]=!f[a[i]];
sum[i]=sum[i-1];
if(f[a[i]]==0)sum[i]--;
else sum[i]++;
// cout<<sum[i]<<' ';
}
// cout<<endl;
for(int i=1;i<=q;i++){
sumsum[i]=sumsum[i-1]+sum[i];
// cout<<sumsum[i]<<' ';
}
// build2(1,n,1);
for(int i=1;i<=q;i++){
ci[a[i]]++;
if(ci[a[i]]%2)last[a[i]]=i;
else{
ans[a[i]]+=sumsum[i-1];
// cout<<ans[a[i]]<<endl;
ans[a[i]]-=sumsum[last[a[i]]-1];
// cout<<ans[a[i]]<<' '<<last[a[i]]<<endl;
}
}
// cout<<ans[1];
// cout<<endl;
for(int i=1;i<=n;i++){
// cout<<last[i]<<' ';
if(ci[i]%2){
// cout<<i<<endl;
ans[i]+=sumsum[q];
ans[i]-=sumsum[last[i]-1];
// cout<<ans[i]<<' ';
}
}
// cout<<endl;
for(int i=1;i<=n;i++){
cout<<ans[i]<<' ';
}
return 0;
}

浙公网安备 33010602011771号