codeforces 903D Almost Difference(递推式)

来源:互联网 发布:淘宝女装店开店经验 编辑:程序博客网 时间:2024/06/11 21:57

题意很简单,自己读吧

思路:
对于 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;}
原创粉丝点击