USACO 2004 MooFest 奶牛集会

题目

问题描述

约翰的n 头奶牛每年都会参加“哞哞大会”。哞哞大会是奶牛界的盛事。集会上的活动很多,比如堆干草,跨栅栏,摸牛仔的屁股等等。它们参加活动时会聚在一起,第i 头奶牛的坐标为Xi,没有两头奶牛的坐标是相同的。奶牛们的叫声很大,第i 头和第j 头奶牛交流,会发出max{Vi;Vj}×|Xi?Xj| 的音量,其中Vi和Vj分别是第i 头和第j 头奶牛的听力。

假设每对奶牛之间同时都在说话,请计算所有奶牛产生的音量之和是多少。

输入文件

第1行:一个整数n(1n20,000)

第2..n+1行:第i+1行有两个整数Vi(1Vi20,000)和Xi(1Xi20,000)

输出文件

仅一行:一个整数表示所有奶牛产生的音量之和。

样例输入输出

moofest.in

4
3 1
2 5
2 6
4 3

moofest.out

57

分析

朴素暴力枚举:枚举i,j,O(n2)。N最大到20000,放弃吧。

首先来观察一下这个音量的计算公式:首先在两只牛的听力v当中取较大值,然后和两者的坐标差相乘。

既然取较大的v,我们不妨把所有奶牛按照v从大到小排序。这样每次取出的奶牛和它右边的奶牛计算即可。

然后再来看如何处理坐标差。因为当前选出的这头奶牛一定是和它右边,也就是较小的奶牛进行计算,所以公式的第一部分是一个定值。那么我们不难想到在这里可以合并同类项。对于一个奶牛它所对应的左半边音量之和的公式就是:当前奶牛听力*(左边奶牛的个数*当前奶牛的坐标-左边所有奶牛的坐标和)。右边也就不难同理得出了。

要计算坐标和,那就树状数组呗。

程序

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN = 20000 + 1;
 4 struct node
 5 {
 6     int x,v,id;
 7 }cow[MAXN];
 8 struct Tree
 9 {
10     long long sum,num;
11 }c[MAXN];
12 int n;
13 bool cmpv(node a,node b)
14 {
15     return a.v>b.v;
16 }
17 bool comp(node a,node b)
18 {
19     return a.x<b.x;
20 }
21 long long ans=0;
22 int main()
23 {
24     freopen("moofest.in","r",stdin);
25     freopen("moofest.out","w",stdout);
26     scanf("%d",&n);
27     for(int i = 1; i <= n; i++)
28         scanf("%d%d",&cow[i].v,&cow[i].x);
29     sort(cow+1,cow+n+1,comp);
30     for(int i = 1; i <= n; i++)
31     {
32         cow[i].id = i;
33         for(int j = i; j <= n; j += j&-j)
34         {
35             c[j].sum+=cow[i].x;
36             c[j].num++;
37         }
38     }
39     sort(cow+1,cow+n+1,cmpv);
40     long long ans=0;
41     for (int i = 1; i <= n; i++)
42     {
43         long long sum = 0, num = 0;
44         for(int j = cow[i].id; j > 0; j -= j&-j)
45         {
46             sum += c[j].sum;
47             num += c[j].num;
48         }
49         ans += (num*cow[i].x-sum)*cow[i].v;
50         sum =- sum, num=-num;
51         for (int j = n; j > 0; j -= j&-j)
52         {
53             sum += c[j].sum;
54             num += c[j].num;
55         }
56         ans += (sum-num*cow[i].x)*cow[i].v;
57         for(int j = cow[i].id; j <= n; j += j&-j)
58         {
59             c[j].sum -= cow[i].x;
60             c[j].num--;
61         }
62     }
63     printf("%lld",ans);
64     return 0;
65 }

原文地址:https://www.cnblogs.com/OIerPrime/p/8976473.html

时间: 2024-08-24 16:43:23

USACO 2004 MooFest 奶牛集会的相关文章

[USACO] 2004 Open MooFest 奶牛集会

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

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

奶牛集会(MooFest, USACO 2004 Open)

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

洞穴奶牛第一话 (Cave Cow 1, USACO 2004 Open)

题目大意: 状压dp #include<bits/stdc++.h> using namespace std; int dp[1<<15][105]; int maps[105][105],s[15]; int main() { int n,m,k,ans=0,res=0; scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=k;i++) { scanf("%d",&s[i]

【洛谷P2345】奶牛集会

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

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 头奶牛的听力.假设每对奶牛之间同时都在说话,请计算所有奶牛产生的音量之和是多少.

Luogu2345 奶牛集会(树状数组)

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

[USACO 04OPEN]MooFest

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