AT_abc390_f [ABC390F] Double Sum 3 点边容斥做法 题解
首先我们了解一下点边容斥,目标是数一个树上的联通块个数,我们知道一棵树有 n 个点,那么就有 n-1 条边,所以只需要数所有的点个数减去所有的边个数就行。 那么这道题实际上是一条链数联通块,那么同样这…
首先我们了解一下点边容斥,目标是数一个树上的联通块个数,我们知道一棵树有 个点,那么就有 条边,所以只需要数所有的点个数减去所有的边个数就行。
那么这道题实际上是一条链数联通块,那么同样这样数就行,从左到右扫描线,记录每个点 上一次出现的位置 ,那么固定 到 ,对于所有的 ,会贡献 个点。
现在来看边,会影响的只有两条边,到 和 ,分析一下到 ,那么需要算出 贡献多少条边,那么就是 ,到 同理。
代码很简洁,轻松最优解:
#include<bits/stdc++.h>
int pre[300010];
int main(){
int i,j,a,n;
long long res=0,cnt=0;
scanf("%d",&n);
for(i=1;i<=n;++i) scanf("%d",&a),res+=(cnt+=i-pre[a]-std::max(pre[a-1]-pre[a],0)-std::max(pre[a+1]-pre[a],0)),pre[a]=i;
printf("%lld",res);
return 0;
}谢谢你,读到这里。
本文同步自洛谷专栏,保留原始正文与发布时间。在洛谷查看原文 ↗