1. 程式人生 > >CF903 D.Almost Difference

CF903 D.Almost Difference

gpo div 之前 部分 ret ++ 就是 其中 題目

題目鏈接:http://codeforces.com/problemset/problem/903/D

題目大意:就是給你n個數a1,a2,…,an,然後在1到n範圍內求函數d(x,y)的和。 這道題可以這麽想,就是先不考慮x,y的大小關系,直接認為d(x,y)= y - x 。記最後結果為sum,那麽sum = ∑d(x,y)=a2 - a1 + a3 - a1 + a3 - a2 + … an - an-1 即sum = ∑d(x,y)=∑(2i - n - 1)ai,其中i = 1到n, 顯然上面的部分很容易求,然後我們只需求出多加的部分和少減的部分。 仔細一想,如果x = a,那麽只有y = a + 1 或 a - 1的時候才會對d(x,y)產生影響,因此我們記錄ai出現的個數。每當記錄下一個ai的個數時,去計算因為這個ai而多算的部分和少算的部分(ai與之前的i - 1個數), 多算的部分就是ai = aj + 1的部分,少算的部分就是ai = aj - 1的部分, j為1到i的任意一個數(i≠j),sum -= 比ai大1的數的個數 sum += 比ai小1的數的個數,處理完的sum就是最後的答案。 另外要註意的是這道題數據範圍大,會爆long long,只能用long double 了。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
double arr[maxn];
int main()
{
  map<double,double>m;
  int n;
  long double sum = 0;
  scanf("%d", &n);
  for(int i = 1; i <= n; i ++){
    scanf("%lf",&arr[i]);
    sum += (i - 1) * (arr[i]);
    sum -= (n - i) * (arr[i]);
    m[arr[i]]
++; sum -= m[arr[i] - 1]; sum += m[arr[i] + 1]; } cout<<fixed<<setprecision(0)<<sum<<endl; return 0; }

CF903 D.Almost Difference