#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
static const int MAX_N = 1000000;
int n;
struct AB { ll a, b; } e[MAX_N];
struct Data
{
int count;
ll sa;
ll w;
Data() { Clear(); }
void Init(int j)
{
count = 1;
sa = e[j].a;
w = e[j].b;
}
void Clear()
{
count = 0;
sa = 0;
w = 0;
}
void Update(int i);
};
Data tree[1 << 21];
void Data::Update(int i)
{
Data& l = tree[2 * i];
Data& r = tree[2 * i + 1];
count = l.count + r.count;
sa = l.sa + r.sa;
w = l.w + r.w + l.count * r.sa;
}
void Update(int i)
{
for (i /= 2; i > 0; i /= 2)
tree[i].Update(i);
}
ll Get()
{
return tree[1].w;
}
ll Use(int j)
{
int i = (1 << 20) + j;
tree[i].Init(j);
Update(i);
return Get();
}
void Clear(int j)
{
int i = (1 << 20) + j;
tree[i].Clear();
Update(i);
}
int order[MAX_N];
void Brute()
{
for (int i = 0; i < n; i++)
order[i] = i;
for (int t = 0; t < n; t++)
{
ll best = -1;
for (int i = t; i < n; i++)
{
ll cur = Use(order[i]);
Clear(order[i]);
if (cur > best)
{
swap(order[t], order[i]);
best = cur;
}
}
printf("%lld\n", Use(order[t]));
}
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%lld%lld", &e[i].a, &e[i].b);
sort(e, e + n, [](const AB& x, const AB& y)
{
if (x.a < y.a)
return true;
else if (x.a > y.a)
return false;
else
return x.b < y.b;
});
Brute();
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | #include <algorithm> #include <cstdio> using namespace std; typedef long long ll; static const int MAX_N = 1000000; int n; struct AB { ll a, b; } e[MAX_N]; struct Data { int count; ll sa; ll w; Data() { Clear(); } void Init(int j) { count = 1; sa = e[j].a; w = e[j].b; } void Clear() { count = 0; sa = 0; w = 0; } void Update(int i); }; Data tree[1 << 21]; void Data::Update(int i) { Data& l = tree[2 * i]; Data& r = tree[2 * i + 1]; count = l.count + r.count; sa = l.sa + r.sa; w = l.w + r.w + l.count * r.sa; } void Update(int i) { for (i /= 2; i > 0; i /= 2) tree[i].Update(i); } ll Get() { return tree[1].w; } ll Use(int j) { int i = (1 << 20) + j; tree[i].Init(j); Update(i); return Get(); } void Clear(int j) { int i = (1 << 20) + j; tree[i].Clear(); Update(i); } int order[MAX_N]; void Brute() { for (int i = 0; i < n; i++) order[i] = i; for (int t = 0; t < n; t++) { ll best = -1; for (int i = t; i < n; i++) { ll cur = Use(order[i]); Clear(order[i]); if (cur > best) { swap(order[t], order[i]); best = cur; } } printf("%lld\n", Use(order[t])); } } int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%lld%lld", &e[i].a, &e[i].b); sort(e, e + n, [](const AB& x, const AB& y) { if (x.a < y.a) return true; else if (x.a > y.a) return false; else return x.b < y.b; }); Brute(); return 0; } |
English