题解:AT_abc347_e [ABC347E] Set Add Query

赛时离 AC\tt AC 只差一点。最可惜的一集。

思路

显然不能每一次都给现在在集合中的元素加,这样一定会 TLE\tt TLE

不妨模仿 ABC346E\tt ABC346E,进行离线操作,即(ii 为当前第 ii 次操作,第 ii 次集合元素为 aia_i 个):

  • jj 元素进入集合时,进行标记,即 lastj=ilast_j=i
  • jj 元素离开集合时,答案增加,ansj=ansj+k=lastj1i1akans_j=ans_j+\sum\limits_{k=last_j-1}^{i-1}a_k

注意:当 jj 元素离开的那一次,它是不会被计算的!

就做完了。

代码实现

#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;
}
posted @   Weslie_qwq  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示