// O^2 log n // do tego raczej niepoprawne :( #include <cstdio> #include <vector> #include <map> #include <set> #include <queue> #include <algorithm> #include <string> #include <sstream> #include <cmath> using namespace std; typedef vector<int> vi; typedef long long ll; typedef vector<ll> vll; typedef pair<int,int> pii; #define mp make_pair #define REP(i,n) for (int i=0,___=(n); i<___; ++i) #define FOR(i,a,b) for (int i=(a),___=(b); i<=___; ++i) #define FORD(i,a,b) for (int i=(a),___=(b); i>=___; --i) #define FOR2(i,a,b) for (int ___A=(a),___B=(b),___BR=1; ___BR; ___BR=0) for (i=___A; i<=___B; ++i) int read() { int n; scanf("%d", &n); return n; } ll readl() { ll n; scanf("%lld", &n); return n; } char readc() { static char s[32]; scanf("%s", s); return *s; } /////////////////////////////////////////////////// /// ZBIORY ROZŁĄCZNE template <int N> class FindUnion { int parent[N]; public: FindUnion() { for (int i=0; i<N; ++i) parent[i] = -1; } int Find(int x) { int result = x, tmp; while (parent[result] >= 0) result = parent[result]; while (x != result) { tmp = parent[x]; parent[x] = result; x = tmp; } return result; } void Union(int x, int y) { x = Find(x); y = Find(y); if (x == y) return; if (parent[x] < parent[y]) { parent[x] += parent[y]; parent[y] = x; } else { parent[y] += parent[x]; parent[x] = y; } } int Size(int x) { return -parent[Find(x)]; } }; int main() { int n = read(); vector<long long> b(n); vector<int> a(n); vector<pair<long long, int> > cur(n); REP(i, n) { a[i] = read(); b[i] = readl(); cur[i].first = b[i]; cur[i].second = i; } vector<int> used; REP(nr, n) { int best = 0; FOR(i, 1, cur.size()-1) { if (cur[i].first > cur[best].first) best = i; } used.push_back(cur[best].second); if (best + 1 < cur.size()) { cur[best] = cur.back(); } cur.pop_back(); vector<pair<int, int> > sorted(used.size()); REP(i, used.size()) { sorted[i].first = a[used[i]]; sorted[i].second = used[i]; } sort(sorted.begin(), sorted.end()); long long res = 0; REP(i, sorted.size()) { int x = sorted[i].second; res += b[x]; res += 1LL * i * a[x]; } printf("%lld\n", res); REP(i, cur.size()) { int x = cur[i].second; cur[i].first += a[x]; } } 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 112 | // O^2 log n // do tego raczej niepoprawne :( #include <cstdio> #include <vector> #include <map> #include <set> #include <queue> #include <algorithm> #include <string> #include <sstream> #include <cmath> using namespace std; typedef vector<int> vi; typedef long long ll; typedef vector<ll> vll; typedef pair<int,int> pii; #define mp make_pair #define REP(i,n) for (int i=0,___=(n); i<___; ++i) #define FOR(i,a,b) for (int i=(a),___=(b); i<=___; ++i) #define FORD(i,a,b) for (int i=(a),___=(b); i>=___; --i) #define FOR2(i,a,b) for (int ___A=(a),___B=(b),___BR=1; ___BR; ___BR=0) for (i=___A; i<=___B; ++i) int read() { int n; scanf("%d", &n); return n; } ll readl() { ll n; scanf("%lld", &n); return n; } char readc() { static char s[32]; scanf("%s", s); return *s; } /////////////////////////////////////////////////// /// ZBIORY ROZŁĄCZNE template <int N> class FindUnion { int parent[N]; public: FindUnion() { for (int i=0; i<N; ++i) parent[i] = -1; } int Find(int x) { int result = x, tmp; while (parent[result] >= 0) result = parent[result]; while (x != result) { tmp = parent[x]; parent[x] = result; x = tmp; } return result; } void Union(int x, int y) { x = Find(x); y = Find(y); if (x == y) return; if (parent[x] < parent[y]) { parent[x] += parent[y]; parent[y] = x; } else { parent[y] += parent[x]; parent[x] = y; } } int Size(int x) { return -parent[Find(x)]; } }; int main() { int n = read(); vector<long long> b(n); vector<int> a(n); vector<pair<long long, int> > cur(n); REP(i, n) { a[i] = read(); b[i] = readl(); cur[i].first = b[i]; cur[i].second = i; } vector<int> used; REP(nr, n) { int best = 0; FOR(i, 1, cur.size()-1) { if (cur[i].first > cur[best].first) best = i; } used.push_back(cur[best].second); if (best + 1 < cur.size()) { cur[best] = cur.back(); } cur.pop_back(); vector<pair<int, int> > sorted(used.size()); REP(i, used.size()) { sorted[i].first = a[used[i]]; sorted[i].second = used[i]; } sort(sorted.begin(), sorted.end()); long long res = 0; REP(i, sorted.size()) { int x = sorted[i].second; res += b[x]; res += 1LL * i * a[x]; } printf("%lld\n", res); REP(i, cur.size()) { int x = cur[i].second; cur[i].first += a[x]; } } return 0; } |