【洛谷P2345】奶牛集会

题目背景

MooFest, 2004 Open

题目描述

约翰的N 头奶牛每年都会参加“哞哞大会”。哞哞大会是奶牛界的盛事。集会上的活动很

多,比如堆干草,跨栅栏,摸牛仔的屁股等等。它们参加活动时会聚在一起,第i 头奶牛的坐标为Xi,没有两头奶牛的坐标是相同的。奶牛们的叫声很大,第i 头和第j 头奶牛交流,会发出max{Vi; Vj}×|Xi ? Xj | 的音量,其中Vi 和Vj 分别是第i 头和第j 头奶牛的听力。假设每对奶牛之间同时都在说话,请计算所有奶牛产生的音量之和是多少。

输入输出格式

输入格式:

? 第一行:单个整数N,1 ≤ N ≤ 20000

? 第二行到第N + 1 行:第i + 1 行有两个整数Vi 和Xi,1 ≤ Vi ≤ 20000; 1 ≤ Xi ≤ 20000

输出格式:

? 单个整数:表示所有奶牛产生的音量之和

输入输出样例

输入样例#1:

4
3 1
2 5
2 6
4 3

输出样例#1:

57

说明

朴素O(N2)

类似于归并排序的二分O(N logN)

树状数组O(N logN)

知识点

树状数组

分析

朴素算法O(N2)能过去一部分点。

题目上给的公式max{Vi; Vj}×|Xi ? Xj |。

我们可以先按照V进行从小到大排序,这样就可以排除V的干扰,也就是保证当前的Vi是最大的。

就可以用树状数组计算前缀和了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=20000+5;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
int n;
int c1[maxn],c2[maxn];
int mx,mn;
struct node
{
    int v,x;
    bool operator < (const node &j) const {
        return v<j.v;
    }
}e[maxn];
void update1(int x,int d)
{while(x<=mx){c1[x]+=d;x+=x&(-x);}}
void update2(int x,int d)
{while(x<=mx){c2[x]+=d;x+=x&(-x);}}
ll ask1(int x)
{ll ans=0;while(x){ans+=c1[x];x-=x&(-x);}return ans;}
ll ask2(int x)
{ll ans=0;while(x){ans+=c2[x];x-=x&(-x);}return ans;}
int main()
{
    n=read();
    for(int i=1;i<=n;i++)
    {
        e[i].v=read();e[i].x=read();
        mx=max(mx,e[i].x);
    }
    sort(e+1,e+n+1);
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        int x=e[i].x,v=e[i].v;
        ll num1,num2,sum1,sum2;
        num1=ask1(x-1);sum1=ask2(x-1);
        num2=ask1(mx)-ask1(x);
        sum2=ask2(mx)-ask2(x);
        ans+=v*(sum2-x*num2+x*num1-sum1);
        update1(x,1);
        update2(x,x);
    }
    printf("%lld\n",ans);
    return 0;
}

  

时间: 2024-10-14 10:31:44

【洛谷P2345】奶牛集会的相关文章

洛谷P2345 奶牛集会

题目背景 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

洛谷P2340 奶牛会展

洛谷P2340 奶牛会展用下标表示智商,值表示情商 1 #include <bits/stdc++.h> 2 #define For(i,j,k) for(int i=j;i<=k;i++) 3 using namespace std ; 4 5 const int N = 411 ; 6 int n,m ; 7 int a[N],b[N],f[800011] ; 8 9 inline int read() 10 { 11 int x = 0 , f = 1 ; 12 char ch =

洛谷P1154 奶牛分厩

题目描述 农夫约翰有N(1<=N<=5000)头奶牛,每头奶牛都有一个唯一的不同于其它奶牛的编号Si,所有的奶牛都睡在一个有K个厩的谷仓中,厩的编号为0到K-1.每头奶牛都知道自己该睡在哪一个厩中,因为约翰教会了它们做除法,Si MOD K的值就是第i头奶年所睡的厩的编号. 给出一组奶牛的编号,确定最小的K使得没有二头或二头以上的奶牛睡在同一厩中. 输入输出格式 输入格式: 第一行一个正整数N,第2到N+1行每行一个整数表示一头奶牛的编号. 输出格式: 单独一行一个整数表示要求的最小的K,对所

P2345 奶牛集会andP2657 低头一族

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

洛谷——P1154 奶牛分厩

P1154 奶牛分厩 题目描述 农夫约翰有N(1<=N<=5000)头奶牛,每头奶牛都有一个唯一的不同于其它奶牛的编号Si,所有的奶牛都睡在一个有K个厩的谷仓中,厩的编号为0到K-1.每头奶牛都知道自己该睡在哪一个厩中,因为约翰教会了它们做除法,Si MOD K的值就是第i头奶年所睡的厩的编号. 给出一组奶牛的编号,确定最小的K使得没有二头或二头以上的奶牛睡在同一厩中. 输入输出格式 输入格式: 第一行一个正整数N,第2到N+1行每行一个整数表示一头奶牛的编号. 输出格式: 单独一行一个整数表

洛谷 P1154 奶牛分厩

P1154 奶牛分厩 农夫约翰有N(1<=N<=5000)头奶牛,每头奶牛都有一个唯一的不同于其它奶牛的编号Si,所有的奶牛都睡在一个有K个厩的谷仓中,厩的编号为0到K-1.每头奶牛都知道自己该睡在哪一个厩中,因为约翰教会了它们做除法,Si MOD K的值就是第i头奶年所睡的厩的编号. 给出一组奶牛的编号,确定最小的K使得没有二头或二头以上的奶牛睡在同一厩中. 输入输出格式 输入格式: 第一行一个正整数N,第2到N+1行每行一个整数表示一头奶牛的编号. 输出格式: 单独一行一个整数表示要求的最

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

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

洛谷P1472 奶牛家谱 Cow Pedigrees

P1472 奶牛家谱 Cow Pedigrees 102通过 193提交 题目提供者该用户不存在 标签USACO 难度普及+/提高 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 农民约翰准备购买一群新奶牛. 在这个新的奶牛群中, 每一个母亲奶牛都生两个小奶牛.这些奶牛间的关系可以用二叉树来表示.这些二叉树总共有N个节点(3 <= N < 200).这些二叉树有如下性质: 每一个节点的度是0或2.度是这个节点的孩子的数目. 树的高度等于K(1 < K < 100).高度是从