AT_abc347_e
题意
给定你一个长度为 \(n\) 且初始全部为 \(0\) 的序列 \(A\),以及一个空集 \(S\)。接下来有 \(T\) 次操作,每次给定一个 \(x\),若 \(x \in S\) 则将 \(x\) 删除,否则将 \(x\) 加入 \(S\)。在每次操作之后,对于 \(j=1,2,\cdots,n\),若 \(j \in S\),则给 \(a_j\) 加上 \(\left| S \right|\),其中 \(\left| S \right|\) 定义为 \(S\) 的元素个数。所有操作完成后,求 \(A\) 的每一个元素的值。
思路
显然,对于 \(x \notin S\) 等价于它后面的每一个位置长度都加 \(1\),\(x \in S\) 等价于后面的每一个位置长度都减 \(1\)。不难想到用差分来修改,再做一遍前缀和即可得到每一次操作做完后的 \(\left| S \right|\)。
接下来如何计算答案呢?读题可以发现,对于一个相同的 \(x\),其一定在第奇数次出现时加入,第偶数次出现时删除。也就是说,在奇数次出现和偶数次出现这段时间内的 $ \sum \left| S \right|$ 是有效的,应计入答案。其余则无效,因为此时 \(x \notin S\)。
注意到要求的 \(\sum \left| S \right|\) 总是连续的,因此可以在前文的基础上再做一次前缀和,即可快速求得答案。
当然了,最后边界记得要处理。时间复杂度是 \(O(n)\) 的。
放上代码方便大家调试:
#include <iostream>
#include <cstdio>
#include <cstring>
#define int long long
using namespace std;
int n,m,x[1000001],a[1000001],s[1000001],pd[1000001],lst[1000001];
signed main()
{
cin >> n >> m;
for( int i = 1 ; i <= m ; i ++ )
{
cin >> x[i];
if( pd[x[i]] ) s[i] --,pd[x[i]] = 0;
else s[i] ++,pd[x[i]] = 1;
}
for( int i = 1 ; i <= m ; i ++ )
s[i] += s[i - 1];
for( int i = 1 ; i <= m ; i ++ )
s[i] += s[i - 1];
memset( pd , 0 , sizeof( pd ) );
for( int i = 1 ; i <= m ; i ++ )
{
if( pd[x[i]] && lst[x[i]] ) a[x[i]] += s[i - 1] - s[lst[x[i]] - 1],pd[x[i]] = 0;
else lst[x[i]] = i,pd[x[i]] = 1;
}
for( int i = 1 ; i <= m ; i ++ )
if( pd[x[i]] )
a[x[i]] += s[m] - s[lst[x[i]] - 1],pd[x[i]] = 0;
for( int i = 1 ; i <= n ; i ++ )
cout << a[i] << ' ';
return 0;
}
还是菜。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现