树状数组的经典应用,这题已经大大超出了我的能力范围之外。。本来树状数组之前就没有用过,加上这题还需要非常巧妙的运用,靠自己能力想我觉得基本不可能想出来了。。对着discuss里的思路一点点的写和改,还是弄了好久,本题需要对树状数组有深入理解才能写出来,数组不是一开始就构造好的,而是遍历的过程中不断地更新,再取和,思路的话discuss中某种大神已经讲的很明白了,不多说了上代码吧
#include<cstdio>
#include<algorithm>
using namespace std;
namespace
{
struct Cow
{
int v, x;
} dat[20000];
int N, bitc[20001], bitt[20001];
bool cmp(struct Cow c1, struct Cow c2)
{
return c1.v < c2.v;
}
int sum(int *b, int i)
{
int s = 0;
while (i > 0)
{
s += b[i];
i -= i & -i;
}
return s;
}
void add(int *b, int i, int x)
{
while (i <= 20000)
{
b[i] += x;
i += i & -i;
}
}
void solve()
{
sort(dat, dat + N, cmp);
long long res = 0;
int total = 0;
for (int i = 0; i < N; i++)
{
if (i)
total += dat[i - 1].x;
int x = dat[i].x;
add(bitc, x, 1);
add(bitt, x, x);
int count = sum(bitc, x);
int dist = sum(bitt, x);
res += 1LL * dat[i].v
* (count * x - dist + total - dist - (i - count) * x);
}
printf("%lld\n", res);
}
}
int main()
{
scanf("%d", &N);
for (int i = 0; i < N; i++)
scanf("%d %d", &dat[i].v, &dat[i].x);
solve();
return 0;
}