2014浙江省赛题。
简单递推。f[i]表示加入第 i 个数字之后答案的新增加量。即以 i 位置作为区间的结尾对答案作出的贡献。
那么很容易得到,f[i]=f[i-1]+a[i]*(i-pre[a[i]]),pre[a[i]]表示a[i]上一次出现的位置。
然后把f[1]到f[n]加起来就是答案了。
#include<cstdio> #include<cstring> #include<cmath> #include<string> #include<vector> #include<queue> #include<algorithm> #include<iostream> using namespace std; const int maxn=100000+10; int T,n; int a[maxn]; int pre[10*maxn]; long long f[maxn]; void init() { memset(f,0,sizeof f); memset(pre,0,sizeof pre); } void read() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); } void work() { long long ans=0; for(int i=1;i<=n;i++) { long long A=(long long)(i-pre[a[i]]); long long B=(long long)a[i]; f[i]=f[i-1]+A*B; pre[a[i]]=i; ans=ans+f[i]; } printf("%lld ",ans); } int main() { scanf("%d",&T); while(T--) { read(); init(); work(); } return 0; }