题解 P2345 【奶牛集会】

题目

一道树状数组的题。

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

首先这个题直接暴力是\(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;
}

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

时间: 2024-10-28 15:25:46

题解 P2345 【奶牛集会】的相关文章

luogu P2345 奶牛集会

二次联通门 : luogu P2345 奶牛集会 /* luogu P2345 奶牛集会 权值线段树 以坐标为下标, 坐标为值建立线段树 对奶牛按听力由小到大排序 对于要查的牛 每次第i次放入奶牛起作用的v就是vi: 每次ans+=(xi*sum-sumxl)*vi+(sumxr-xi*sum)*vi */ #include <algorithm> #include <cstdio> #define Max 400003 void read (int &now) { now

P2345 奶牛集会andP2657 低头一族

做法是一样的 题目背景 MooFest, 2004 Open 题目描述 约翰的N 头奶牛每年都会参加"哞哞大会".哞哞大会是奶牛界的盛事.集会上的活动很 多,比如堆干草,跨栅栏,摸牛仔的屁股等等.它们参加活动时会聚在一起,第i 头奶牛的坐标为Xi,没有两头奶牛的坐标是相同的.奶牛们的叫声很大,第i 头和第j 头奶牛交流,会发出max{Vi; Vj}×|Xi ? Xj | 的音量,其中Vi 和Vj 分别是第i 头和第j 头奶牛的听力.假设每对奶牛之间同时都在说话,请计算所有奶牛产生的音量

洛谷P2345 奶牛集会

题目背景 MooFest, 2004 Open 题目描述 约翰的N 头奶牛每年都会参加"哞哞大会".哞哞大会是奶牛界的盛事.集会上的活动很 多,比如堆干草,跨栅栏,摸牛仔的屁股等等.它们参加活动时会聚在一起,第i 头奶牛的坐标为Xi,没有两头奶牛的坐标是相同的.奶牛们的叫声很大,第i 头和第j 头奶牛交流,会发出max{Vi; Vj}×|Xi ? Xj | 的音量,其中Vi 和Vj 分别是第i 头和第j 头奶牛的听力.假设每对奶牛之间同时都在说话,请计算所有奶牛产生的音量之和是多少.

luogu P2345 奶牛集会 |排序+树状数组

题目描述 约翰的N 头奶牛每年都会参加"哞哞大会".哞哞大会是奶牛界的盛事.集会上的活动很多,比如堆干草,跨栅栏,摸牛仔的屁股等等.它们参加活动时会聚在一起,第i 头奶牛的坐标为Xi,没有两头奶牛的坐标是相同的.奶牛们的叫声很大,第i 头和第j 头奶牛交流,会发出max{Vi; Vj}×|Xi ? Xj | 的音量,其中Vi 和Vj 分别是第i 头和第j 头奶牛的听力. 假设每对奶牛之间同时都在说话,请计算所有奶牛产生的音量之和是多少. 输入格式 ? 第一行:单个整数N,1 ≤ N ≤

【洛谷P2345】奶牛集会

题目背景 MooFest, 2004 Open 题目描述 约翰的N 头奶牛每年都会参加"哞哞大会".哞哞大会是奶牛界的盛事.集会上的活动很 多,比如堆干草,跨栅栏,摸牛仔的屁股等等.它们参加活动时会聚在一起,第i 头奶牛的坐标为Xi,没有两头奶牛的坐标是相同的.奶牛们的叫声很大,第i 头和第j 头奶牛交流,会发出max{Vi; Vj}×|Xi ? Xj | 的音量,其中Vi 和Vj 分别是第i 头和第j 头奶牛的听力.假设每对奶牛之间同时都在说话,请计算所有奶牛产生的音量之和是多少.

奶牛集会(MooFest, USACO 2004 Open)

题目背景 MooFest, 2004 Open 题目描述 约翰的N 头奶牛每年都会参加"哞哞大会".哞哞大会是奶牛界的盛事.集会上的活动很 多,比如堆干草,跨栅栏,摸牛仔的屁股等等.它们参加活动时会聚在一起,第i 头奶牛的坐标为Xi,没有两头奶牛的坐标是相同的.奶牛们的叫声很大,第i 头和第j 头奶牛交流,会发出max{Vi; Vj}×|Xi ? Xj | 的音量,其中Vi 和Vj 分别是第i 头和第j 头奶牛的听力.假设每对奶牛之间同时都在说话,请计算所有奶牛产生的音量之和是多少.

USACO 2004 MooFest 奶牛集会

题目 问题描述 约翰的n 头奶牛每年都会参加"哞哞大会".哞哞大会是奶牛界的盛事.集会上的活动很多,比如堆干草,跨栅栏,摸牛仔的屁股等等.它们参加活动时会聚在一起,第i 头奶牛的坐标为Xi,没有两头奶牛的坐标是相同的.奶牛们的叫声很大,第i 头和第j 头奶牛交流,会发出max{Vi;Vj}×|Xi?Xj| 的音量,其中Vi和Vj分别是第i 头和第j 头奶牛的听力. 假设每对奶牛之间同时都在说话,请计算所有奶牛产生的音量之和是多少. 输入文件 第1行:一个整数n(1n20,000) 第2

[USACO] 2004 Open MooFest 奶牛集会

题目背景 MooFest, 2004 Open 题目描述 约翰的N 头奶牛每年都会参加"哞哞大会".哞哞大会是奶牛界的盛事.集会上的活动很 多,比如堆干草,跨栅栏,摸牛仔的屁股等等.它们参加活动时会聚在一起,第i 头奶牛的坐标为Xi,没有两头奶牛的坐标是相同的.奶牛们的叫声很大,第i 头和第j 头奶牛交流,会发出\(max{Vi, Vj}\) \(×\) \(|Xi ? Xj |\) 的音量,其中Vi 和Vj 分别是第i 头和第j 头奶牛的听力.假设每对奶牛之间同时都在说话,请计算所有

Luogu2345 奶牛集会(树状数组)

题目背景 MooFest, 2004 Open 题目描述 约翰的 \(N\) 头奶牛每年都会参加"哞哞大会".哞哞大会是奶牛界的盛事.集会上的活动很多,比如堆干草,跨栅栏,摸牛仔的屁股等等.它们参加活动时会聚在一起,第i 头奶牛的坐标为 \(Xi\),没有两头奶牛的坐标是相同的.奶牛们的叫声很大,第i 头和第j 头奶牛交流,会发出 \(max[Vi,Vj]×|Xi?Xj|\) 的音量,其中 \(Vi\) 和 \(Vj\) 分别是第 \(i\) 头和第 \(j\) 头奶牛的听力. 假设每