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; }