[ABC347E] Set Add Query题解
思路
通过读题发现,每个数变化当且仅当这个数在集合内。所以不妨设它被添加进来的时间点为 ,它被删除的时间点为 ,所以它被增加的数量就是这段时间内集合数量之和。所以用一个变量 模拟当前集合内有多少个数,前缀和维护即可。具体实现参见代码。
代码
#include<bits/stdc++.h> using namespace std; #define int long long int a[200010]; int sum[200010]; unordered_map<int,int> mp;// map判重 int ans[200010]; int p[200010];// 每个数出现的位置, 相当于 L_i signed main() { int n,m; cin>>n>>m; for(int i=1;i<=m;i++) cin>>a[i]; int cnt=0; for(int i=1;i<=n;i++) p[i]=1; for(int i=1;i<=m;i++) { if(mp[a[i]]==1) {// 重复了 ans[a[i]]+=sum[i-1]-sum[p[a[i]]-1]; cnt--; mp[a[i]]=0; p[a[i]]=i; } else { // 没有重复 cnt++; mp[a[i]]=1; p[a[i]]=i; } sum[i]=cnt; sum[i]=sum[i-1]+sum[i]; //cout<<sum[i]<<" "; } //cout<<sum[4]<<"\n"; for(int j=1;j<=n;j++) { int i=m+1; a[i]=j; if(mp[a[i]]==1) { ans[a[i]]+=sum[m]-sum[p[a[i]]-1]; //cout<<m<<" "<<p[i]-1<<"\n"; cnt--; mp[a[i]]=0; } else { cnt++; mp[a[i]]=1; } } for(int i=1;i<=n;i++) cout<<ans[i]<<" "; return 0; }
本文作者:merlinkkk
本文链接:https://www.cnblogs.com/merlinkkk/p/18306127
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步