#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; } |
English