分析:
20000的数据规模,暴力肯定是要超时。直观的是要求和,为了减少求和的次数,考虑运用树状数组。
发现,可以先按音量排序,然后只需要求距离,用树状数组可以很好的解决。
心得:
abs()函数使用失败!原因:不支持64int。
// 528K 79MS
// abs()函数使用失败
/*
1. 将数据按音量升序排列;
2. t1[]用来求距离和。
3. t2[]用来求cow的个数。
*/
#include < stdio.h >
#include < stdlib.h >
#include < string .h >
#include < algorithm >
using namespace std;
#define NL 20001
#define LL __int64
int t2[NL];
int n, mx;
LL t1[NL];
struct vol {
int v, x;
bool operator < ( const vol & a) const {
return v < a.v;
}
}vo[NL];
LL ABS(LL x)
{
if (x < 0 ) return - x;
return x;
}
inline int lowbit( int idx)
{
return idx & ( - idx);
}
void update( int x, int c)
{
int x1 = x;
while (x <= mx) {
t1[x] += x1;
t2[x] += c;
x += lowbit(x);
}
}
LL sum( int x, LL & c)
{
LL cnt = 0 ;
c = 0 ;
while (x > 0 ) {
cnt += t1[x];
c += t2[x];
x -= lowbit(x);
}
return cnt;
}
int main()
{
int i;
LL ans;
// freopen("in.txt", "r", stdin);
while (scanf( " %d " , & n) != EOF) {
mx = 0 ;
for (i = 0 ; i < n; i ++ ) {
scanf( " %d%d " , & vo[i].v, & vo[i].x);
if (vo[i].x > mx) mx = vo[i].x;
}
sort(vo, vo + n);
memset(t1, 0 , sizeof (t1));
memset(t2, 0 , sizeof (t2));
update(vo[ 0 ].x, 1 );
ans = 0 ;
/*
k1:比cow_i位置大的距离和。
k2:比cow_i位置小的距离和。
m1:比cow_i位置大的cow的个数。
m2:比cow_i位置小的cow的个数。
*/
for (i = 1 ; i < n; i ++ ) {
LL k1, k2;
LL c1, c2, m1, m2;
k1 = sum(mx, c1) - sum(vo[i].x, c2);
m1 = c1 - c2;
k2 = sum(vo[i].x - 1 , m2);
ans += (ABS(k1 - m1 * vo[i].x) + ABS(k2 - m2 * vo[i].x)) * vo[i].v;
update(vo[i].x, 1 );
}
printf( " %I64d\n " , ans);
}
return 0 ;
}