Educational Codeforces Round 47 (Rated for Div. 2) :C. Annoying Present(等差求和)

题目链接:http://codeforces.com/contest/1009/problem/C

解题心得:

  • 题意就是一个初始全为0长度为n的数列,m此操作,每次给你两个数x、d,你需要在数列中选一个位置pos,然后对于每一个位置i的数num[i]-x+d*dis(i,pos)。最后要求这个数列平均值最大。
  • 其实不需要记录这个数列中的每个数是多少,只需要记录总和就行了。如果d为正数pos选在数列越中间的位置最后的总和越大。所以需要分类讨论d的正负和数列长度的奇偶,然后用等差通项求和公式就行了。
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;

ll sum = 0;
ll n,m;

void init() {
    scanf("%lld%lld",&n,&m);
}

ll sum_x = 0;

void odd(ll x){
    ll cut = n/2;
    if(x > 0){
        double t;
        t = (double)n/2.0;
        sum += t*(double)(n-1)*(double)x;
    } else {
        sum += (1+cut)*cut*x;
    }
}

void even(ll x){
    ll cut = n/2-1;
    if(x>0) {
        double t;
        t = (double)n/2.0;
        sum += t*(double)(n-1)*(double)x;
    } else {
        sum += (1 + cut) * cut * x;
        sum += n / 2 * x;
    }
}

void solve(){
    while(m--){
        ll x,d;
        scanf("%lld%lld",&x,&d);
        sum_x += x*n;
        if(n%2){
            odd(d);
        } else {
            even(d);
        }
    }
    sum += sum_x;
    double ans = (double)sum/(double)n;
    printf("%.12f",ans);
}

int main() {
    init();
    solve();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/GoldenFingers/p/9358621.html