题意:FJ有n头牛,排列成一条直线(不会在同一个点),给出每头牛在直线上的坐标x。另外,每头牛还有一个自己的声调v,如果两头牛(i和j)之间想要沟通的话,它们必须用同个音调max(v[i],v[j]),沟通起来消耗的能量为:max(v[i],v[j]) * 它们之间的距离。问要使所有的牛之间都能沟通(两两之间),总共需要消耗多少能量。
思路:树状数组。很好的一道题。把牛按x升序排列,然后:(很难表示清楚,囧...)
1:把沟通分成向左和向右,向左就是:v[右] > v[左],它们之间取右边牛的声调。
2:先求向左的总能量:运用2个树状数组,都以牛的声调做下标,arNum[]用于求某个声调范围内牛的数量,arDis[]用于求某个声调范围内牛的总距离(与起点0的总距离),这对于当前的牛(x,v)来说,用它的音调向左沟通消耗的总能量则为:v * 左边声调比它小的牛和它的距离差之和(sum(v-1, arNum)* sum(v-1, arDis))。
3:相同的道理求出向右的总能量。
代码如下:
#include<iostream>
#include<algorithm>
#define lowbit(x) (x&(-x))
using namespace std;
const int MAX = 20005;
struct data
{
int x, w;
}cow[MAX];
int arNum[MAX], arDis[MAX];
bool cmp(data a, data b)
{
return a.x < b.x;
}
void add(int i, int *ar, int w)
{
while(i <= MAX-1)
{
ar[i] += w;
i += lowbit(i);
}
}
__int64 sum(int i, int *ar)
{
__int64 ans = 0;
while(i > 0)
{
ans += ar[i];
i -= lowbit(i);
}
return ans;
}
int main()
{
int n, i;
__int64 preNum, preDis;
scanf("%d", &n);
for(i = 0; i < n; i ++)
scanf("%d%d", &cow[i].w, &cow[i].x);
sort(cow, cow + n, cmp);
__int64 ans = 0;
memset(arNum, 0, sizeof(arNum)); // 求向左的总能量。
memset(arDis, 0, sizeof(arDis));
for(i = 0; i < n; i ++)
{
preNum = sum(cow[i].w-1, arNum);
preDis = sum(cow[i].w-1, arDis);
ans += (preNum * cow[i].x - preDis) * cow[i].w;
add(cow[i].w, arNum, 1);
add(cow[i].w, arDis, cow[i].x);
}
memset(arNum, 0, sizeof(arNum)); // 求向右的总能量。
memset(arDis, 0, sizeof(arDis));
for(i = n-1; i >= 0; i --)
{
preNum = sum(cow[i].w, arNum); // 这里不要用w-1,考虑了声调相等的情况。
preDis = sum(cow[i].w, arDis);
ans += (preDis - preNum * cow[i].x) * cow[i].w;
add(cow[i].w, arNum, 1);
add(cow[i].w, arDis, cow[i].x);
}
printf("%I64d\n", ans);
return 0;
}
分享到:
相关推荐
poj上第1990题目源码,用到了2个树状数组,这题数据结构是关键,想到了题目就很简单了
POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类
poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题...
POJ第1861题源码 POJ第1861题源码 POJ第1861题源码
北大POJ1159-Palindrome 解题报告+AC代码
poj分类poj分类poj分类poj分类
C语言 poj npu 西工大 C语言Poj答案全完整打包,给有需要的朋友
poj 3414解题报告poj 3414解题报告poj 3414解题报告poj 3414解题报告
poj 1012解题报告poj 1012解题报告poj 1012解题报告poj 1012解题报告
poj 2329解题报告poj 2329解题报告poj 2329解题报告poj 2329解题报告
poj 1659解题报告poj 1659解题报告poj 1659解题报告poj 1659解题报告
POJ1503解答 POJ1503解答,正确答案(已通过POJ)
北大POJ2002-Squares 解题报告+AC代码
POJ1048,加强版的约瑟夫问题 难度中等
POJ1083的代码,POJ1083的代码,POJ1083的代码
poj 百练 题目分类 poj 百练 题目分类
poj 1001答案
POJ2968代码有用,欢迎下载,POJ代码
POJ上的一道题目,自己写的代码,因为想下载别人的, 所以就放上了。
poj 1440解题报告 poj 1440解题报告 poj 1440解题报告 poj 1440解题报告