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
#include<algorithm>
#include<iostream>
#include<list>
#include<map>
#include<queue>
#define FOR(i,n) for(int i = 0;i<n;++i)
#define FORI(i,b,n) for(int i = b;i<n;++i)
#define FORD(i,n) for(int i = n;i>=0;--i)
#define ZERO 0.000001
#define MAX ((1<<31)-1)
#define qprintf debug && printf
#define ull long long int
using namespace std;
//int debug=0;
//#define dcout debug && cout
class P
{
	public: P(){}P(ull x,ull y,ull value):x(x),y(y),value(value){}
	ull x,y;
	ull value;
};
struct C
{
	bool operator()(const P &a,const P &b){
		return a.x==b.x ? a.y>b.y : a.x<b.x; 
	}
};
int main(){
	ios_base::sync_with_stdio(0);
	int e,s;
	cin>>e>>s;
	//wczyt6aj w,h
	ull w,h;
	cin>>w>>h;

	//wczytaj punkty
		//przekonwertuj na prostokątny
	int es=e+s;
	P*t=new P[es];
	FOR(i,e){
		ull x,y,v;
		cin>>x>>y>>v;
		x*=h;
		y*=w;
		t[i].x=x-y;
		t[i].y=(x+y);
		t[i].value=v;
	}
	FOR(i,s){
		ull x,y,v;
		cin>>x>>y>>v;
		x*=h;
		y*=w;
		t[i+e].x=x-y;
		t[i+e].y=(x+y);
		t[i+e].value=-v;
	}

	//posortuj
	C c;
	sort(t,t+e+s,c);

	//dla każdego punktu
	ull robbed=0;
	map<ull,ull> m;
	FOR(i,es){
		//jeśli to strażnik
		if(t[i].value<0){
			//to go wstaw
			//dcout<<"adding guard at "<<t[i].y<<" from ("<<t[i].x<<","<<t[i].y<<"), he wants "<<t[i].value<<endl;
			m[t[i].y]=t[i].value;
		}
		//jeśli to skarb
		else{
			//dcout<<"adding a trasuse at "<<t[i].y<<" from ("<<t[i].x<<","<<t[i].y<<"), it is worth "<<t[i].value<<endl;
			//to dla każdego poprzedniego zredukuj
			map<ull,ull>::iterator it = m.lower_bound(t[i].y);
			map<ull,ull>::iterator ite = m.end();
			ull cash = t[i].value;
			while(it!=ite){
				//jeśli tego całkowicie przekupisz
				if(cash+ it->second >=0){
					cash+=it->second;
					//dcout<<"This treasure allows me to bribe totally a guard at "<<it->first<<", i give him "<<it->second<<", and i am left with "<<cash<<endl;
					m.erase(it);
					it = m.lower_bound(t[i].y);
				}else{
					//to chociaż trochę
					it->second+=cash;
					//dcout<<"This treasure allows me to bribe a little a guard at "<<it->first<<", i give him "<<cash<<", and he still wants "<<it->second<<endl;
					cash=0;
					++it;
					break;
				}
			}
			//jeśli coś zostało, do dodaj do wyniku
			//dcout<<"I am left with "<<cash<<endl;
			if(cash>0){
				robbed+=cash;
			}
		}

	}
	//wyświetl wynik
	cout<<robbed<<endl;
	return 0;
}