#include <cstdio> #include <cmath> #include <vector> #include <algorithm> #include <utility> using namespace std; typedef long long int ll; const ll minfty = -1e18; typedef long double ld; const ld eps = 1e-10; inline bool rowne(ld a, ld b) { return abs(a - b) < eps; } inline bool mniejsze(ld a, ld b) { return !rowne(a, b) && a < b; } inline bool wieksze(ld a, ld b) { return !rowne(a, b) && a > b; } int n, d, u; int w, h; struct punkt { ld x, y; int war; punkt(int xx, int yy, int v) : war(v) { x = (xx + (((ld) w) * yy) / h) / (2.0L * w); y = ((((ld) w) * yy) / h - xx) / (2.0L * w); } void wypisz() const { printf("P(%.2Lf, %.2Lf : %d)\n", x, y, war); } }; inline bool operator< (const punkt &a, const punkt &b) { if(rowne(a.y, b.y)) return mniejsze(a.x, b.x); return mniejsze(a.y, b.y); } vector<punkt> punkty; vector<ld> iksy; inline int pos(ld iks) { return lower_bound(iksy.begin(), iksy.end(), iks, mniejsze) - iksy.begin(); } int n2; ll drz[1200005]; ll spu[1200005]; void spusc(int w) { drz[w] += spu[w]; if(w < n2) { spu[w * 2] += spu[w]; spu[w * 2 + 1] += spu[w]; } spu[w] = 0LL; } void dodaj(int w, int a, int b, int p, int k, ll war) { spusc(w); if(b < p || k < a) return; if(a <= p && k <= b) { spu[w] = war; spusc(w); return; } dodaj(w * 2, a, b, p, (p + k) / 2, war); dodaj(w * 2 + 1, a, b, (p + k) / 2 + 1, k, war); drz[w] = max(drz[w * 2], drz[w * 2 + 1]); } ll odczytaj(int w, int a, int b, int p, int k) { spusc(w); if(b < p || k < a) return minfty; if(a <= p && k <= b) return drz[w]; return max( odczytaj(w * 2, a, b, p, (p + k) / 2), odczytaj(w * 2 + 1, a, b, (p + k) / 2 + 1, k) ); } int main() { scanf("%d%d", &d, &u); scanf("%d%d", &w, &h); n = d + u; for(int i = 0; i < n; i++) { int x, y, v; scanf("%d%d%d", &x, &y, &v); if(i >= d) v *= -1; punkty.push_back(punkt(x, y, v)); } sort(punkty.begin(), punkty.end()); for(const punkt &p : punkty) iksy.push_back(p.x); sort(iksy.begin(), iksy.end(), mniejsze); iksy.resize(unique(iksy.begin(), iksy.end(), rowne) - iksy.begin()); n2 = 1; while(n2 <= iksy.size()) n2 *= 2; for(const punkt &p : punkty) { int poz = pos(p.x); ll ile = odczytaj(1, poz, poz, 0, n2 - 1); ll pop = max(odczytaj(1, poz, n2 - 1, 0, n2 -1), 0LL); if(ile < pop) dodaj(1, poz, poz, 0, n2 - 1, pop - ile); dodaj(1, 0, poz, 0, n2 - 1, p.war); } printf("%lld\n", odczytaj(1, 0, n2 - 1, 0, n2 - 1)); 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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | #include <cstdio> #include <cmath> #include <vector> #include <algorithm> #include <utility> using namespace std; typedef long long int ll; const ll minfty = -1e18; typedef long double ld; const ld eps = 1e-10; inline bool rowne(ld a, ld b) { return abs(a - b) < eps; } inline bool mniejsze(ld a, ld b) { return !rowne(a, b) && a < b; } inline bool wieksze(ld a, ld b) { return !rowne(a, b) && a > b; } int n, d, u; int w, h; struct punkt { ld x, y; int war; punkt(int xx, int yy, int v) : war(v) { x = (xx + (((ld) w) * yy) / h) / (2.0L * w); y = ((((ld) w) * yy) / h - xx) / (2.0L * w); } void wypisz() const { printf("P(%.2Lf, %.2Lf : %d)\n", x, y, war); } }; inline bool operator< (const punkt &a, const punkt &b) { if(rowne(a.y, b.y)) return mniejsze(a.x, b.x); return mniejsze(a.y, b.y); } vector<punkt> punkty; vector<ld> iksy; inline int pos(ld iks) { return lower_bound(iksy.begin(), iksy.end(), iks, mniejsze) - iksy.begin(); } int n2; ll drz[1200005]; ll spu[1200005]; void spusc(int w) { drz[w] += spu[w]; if(w < n2) { spu[w * 2] += spu[w]; spu[w * 2 + 1] += spu[w]; } spu[w] = 0LL; } void dodaj(int w, int a, int b, int p, int k, ll war) { spusc(w); if(b < p || k < a) return; if(a <= p && k <= b) { spu[w] = war; spusc(w); return; } dodaj(w * 2, a, b, p, (p + k) / 2, war); dodaj(w * 2 + 1, a, b, (p + k) / 2 + 1, k, war); drz[w] = max(drz[w * 2], drz[w * 2 + 1]); } ll odczytaj(int w, int a, int b, int p, int k) { spusc(w); if(b < p || k < a) return minfty; if(a <= p && k <= b) return drz[w]; return max( odczytaj(w * 2, a, b, p, (p + k) / 2), odczytaj(w * 2 + 1, a, b, (p + k) / 2 + 1, k) ); } int main() { scanf("%d%d", &d, &u); scanf("%d%d", &w, &h); n = d + u; for(int i = 0; i < n; i++) { int x, y, v; scanf("%d%d%d", &x, &y, &v); if(i >= d) v *= -1; punkty.push_back(punkt(x, y, v)); } sort(punkty.begin(), punkty.end()); for(const punkt &p : punkty) iksy.push_back(p.x); sort(iksy.begin(), iksy.end(), mniejsze); iksy.resize(unique(iksy.begin(), iksy.end(), rowne) - iksy.begin()); n2 = 1; while(n2 <= iksy.size()) n2 *= 2; for(const punkt &p : punkty) { int poz = pos(p.x); ll ile = odczytaj(1, poz, poz, 0, n2 - 1); ll pop = max(odczytaj(1, poz, n2 - 1, 0, n2 -1), 0LL); if(ile < pop) dodaj(1, poz, poz, 0, n2 - 1, pop - ile); dodaj(1, 0, poz, 0, n2 - 1, p.war); } printf("%lld\n", odczytaj(1, 0, n2 - 1, 0, n2 - 1)); return 0; } |