题意很简单,自己读吧
思路:
对于 1,2,3,1,3,记录前缀和,思考前面的所有数到这个数的情况
a[i]*(i-1) - sum[i-1],即不考虑(a[i]-1和a[i]+1的数时,前面所有数到a[i]的结果,因为对于每个a[i]-1,相当于多加了一个1,对于每个a[i]+1,相当于多减了个1,所以用map统计前面每个数出现的次数。最后再把距离为1的数补回来即可。
代码如下:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
using namespace std;
typedef long double ld;
typedef long long ll;
const int MAX = 200010;
ll sum[MAX];
ll a[MAX],N;
map<ll,int> mp;
int main(void){
memset(sum,0,sizeof(sum));
scanf("%lld",&N);
for(int i=1;i<=N;++i){
scanf("%lld",&a[i]);
sum[i] = sum[i-1] + a[i];
}
ld res = 0;//最大的可能结果是N^N/2*a[i]所以肯可能爆ll,这题用ld。
for(int i=1;i<=N;++i){
ld temp = (ld)a[i];//考虑对于这个一位数的情况.
temp = temp*(i-1);
temp -= sum[i-1];
if(mp.count(a[i] - 1)){//去掉多加的
temp -= mp[a[i]-1];
}
if(mp.count(a[i]+1)){//补上多减的
temp += mp[a[i]+1];
}
mp[a[i]]++;
res += temp;
}
printf("%.0Lf\n",res);
return 0;
}