码迷,mamicode.com
首页 > 其他好文 > 详细

题解 P2345 【奶牛集会】

时间:2019-12-29 10:45:14      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:需要   owb   typedef   树状   加强   直接   lin   str   max   

题目

一道树状数组的题。

话说题目直接告诉做法是什么鬼?

首先这个题直接暴力是\(O(n^2)\)的,不能通过(评论里说可以?可能数据太水了,建议加强

考虑优化,首先对于答案里的\(max\),可以直接通过排序优化掉,即把数据从小到大排序,每次更新答案的时候就直接使用当前的\(V\)就可以了。

之后看这个式子:\(|X_i - X j|\)。单独看没有什么特点,但是如果我们对于\(i\),讨论一下\(j\),就可以发现规律。显然对于\(j\),可以分成两类,即\(\{j_1|X_{j1}<X_i \}\)\(\{ j_2|X_{j2}>X_i \}\)。设当前\(i\)两边分别有\(x_1,x_2\)\(j\),那么答案就是\((x_1\times X_i- \Sigma X_{j1})+(\Sigma X_{j2}-x_2 \times X_i)\)

显然对于\(\Sigma X_{j1}\),可以用前缀和直接求出。对于\(\Sigma X_{j2}\),只需要用总的减去\(\Sigma X_{j1}\)就可以求出。

\(x_1,x_2\)同理也可以求出

这里选择树状数组。

最后别忘了开longlong,否则100pts->45pts。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 20005;
typedef long long ll;
int n;
ll iAns, iSum[N], iCnt[N];
struct sCow
{
    int V, X;
}cow[N];

inline bool cmp(sCow a, sCow b){return a.V < b.V;}
inline int lowbit(int x){return x & -x;}
inline void Add(int x, int k){for(; x <= N; x += lowbit(x)) iSum[x] += k, iCnt[x] += 1;}
inline void Query(int x, ll &ans, int &cnt){ans = 0, cnt = 0;for(; x; x -= lowbit(x)) ans += iSum[x], cnt += iCnt[x];}
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d%d", &cow[i].V, &cow[i].X);
    sort(cow + 1, cow + 1 + n, cmp);
    ll S = 0, C = 0;
    for(int i = 1; i <= n; i++)
    {
        ll ans = 0;
        int cnt = 0;
        Query(cow[i].X, ans, cnt);
        iAns += cow[i].V * (cnt * cow[i].X - ans);
        iAns += cow[i].V * ((S - ans) - (C - cnt) * cow[i].X);
        Add(cow[i].X, cow[i].X);
        S += cow[i].X, C +=1;
    }
    cout << iAns;
}

题解 P2345 【奶牛集会】

标签:需要   owb   typedef   树状   加强   直接   lin   str   max   

原文地址:https://www.cnblogs.com/lcezych/p/12114134.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!