Problem:
Problem H:
迷い猫、走った
洋菓子専門店ストレイキャッツではたくさんの猫が飼われている。猫の数があまりにも多いため、この店のスタッフである希は餌やりに困っていた。
いくつかの場所に餌を置いても、猫は貪欲なので最も近い餌に向かってしまい、一つの餌入れにたくさんの猫が集中してしまう。
あなたは希のために、できるだけ猫が集中しない餌の配置を求める問題を解くことにした。
問題を簡単にするため、猫は平面上の y>0 の部分にいて餌を置くまで動かないとする。
猫は N 個の集団に分かれていて、一箇所に何匹もいるかもしれない。
餌入れは y=0 上の M 点に固定してあり、この中からいくつか選んで餌を入れることになる。
餌を入れると、猫は(ユークリッド距離で)一番近い餌の入った餌入れに向かうが、同じ距離に二つあるときはx座標が小さいほうに向かうものとする。
この条件の下で、最も猫が集まっている餌入れの猫の数を最小化しなさい。
Input
入力は以下のような形式で与えられる。
N M
x
1
y
1
C
1
...
x
N
y
N
C
N
x
1
...
x
M
入力の1行目には、2つの整数 N, M がスペース文字で区切られて与えられる。これらは、問題文で指定したとおりである。0 ≤ N ≤ 1000 および 1 ≤ M ≤ 1000 を満たす。
続く N 行には、それぞれの猫の集団について1行に1つずつ、集団の位置の x, y 座標を表す整数の組
(-10000 ≤ x ≤ 10000, 0 < y ≤ 10000)と何匹集まっているかを表す整数C(1 ≤ C ≤ 100000)が与えられる。
その後のM行には、それぞれの餌入れについて1行に1つずつ、餌入れの位置のx座標を表す整数(-10000 ≤ x ≤ 10000)が与えられる。
同じ点に、二つ以上の餌入れが存在することはない。
Output
最も猫が集まっている餌入れの猫の数の最小値を出力せよ。
Notes on Test Cases
上記入力形式で複数のデータセットが与えられます。各データセットに対して上記出力形式で出力を行うプログラムを作成して下さい。
N, M がともに 0 のとき入力の終わりを示します。
Sample Input
3 3
-1 1 1
0 1 1
1 1 1
-3
0
3
5 5
7 3 5
-9 2 7
4 9 6
10 5 9
-9 7 9
0
-1
-2
-9
-8
0 0
Output for Sample Input
2
20

Submitted solutions:

code_snippet: // AOJ #2211
// Stray Cats, Run... 2025.2.13

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
 
struct State { int i, j; };
 
bool feasible(ll L, const vector<int>& xGroups, const vector<ll>& weights,
    const vector<ll>& prefix, const vector<int>& bowls) {
    int n = xGroups.size();
    int m = bowls.size();
    if(n == 0) return true;
    
    vector<int> nextRange(n, 0);
    int r = 0;
    for (int s = 0; s < n; s++) {
        if(r < s) r = s;
        while(r < n && (prefix[r+1] - prefix[s]) <= L) r++;
        nextRange[s] = r - 1;
    }
 
    vector<vector<bool>> visited(n, vector<bool>(m, false));
    deque<State> dq;
 
    int firstMax = nextRange[0];
    for (int j = 0; j < m; j++){
        for (int r = 0; r <= firstMax; r++){
            if(!visited[r][j]){
                visited[r][j] = true;
                dq.push_back({r, j});
            }
        }
    }
 
    while(!dq.empty()){
        State cur = dq.front();
        dq.pop_front();
        int i = cur.i, j = cur.j;
        if(i == n-1) return true;
 
        int nextStart = i + 1;
        ll b_curr = bowls[j];
        int lowerBound = max(bowls[j] + 1, 2 * xGroups[i] - (int)b_curr);
        int upperBound = 2 * xGroups[nextStart] - (int)b_curr;
 
        int kLow, kHigh;
        {
            int lo = j+1, hi = m;
            while(lo < hi){
                int mid = (lo + hi) / 2;
                if(bowls[mid] < lowerBound) lo = mid + 1;
                else hi = mid;
            }
            kLow = lo;
        }
        {
            int lo = j+1, hi = m;
            while(lo < hi){
                int mid = (lo + hi) / 2;
                if(bowls[mid] < upperBound) lo = mid + 1;
                else hi = mid;
            }
            kHigh = lo;
        }
 
        int newMax = nextRange[nextStart];
        for (int k = kLow; k < kHigh; k++){
            for (int rNew = nextStart; rNew <= newMax; rNew++){
                if(!visited[rNew][k]){
                    visited[rNew][k] = true;
                    dq.push_back({rNew, k});
                }
            }
        }
    }
    return false;
}
 
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
 
    while(true){
        int N, M;
        cin >> N >> M;
        if(M==0) break;
 
        map<int, ll> catMap;
        for (int i = 0; i < N; i++){
            int x, y; ll c;
            cin >> x >> y >> c;
            catMap[x] += c;
        }
        vector<int> xGroups;
        vector<ll> weights;
        for(auto &p : catMap){
            xGroups.push_back(p.first);
            weights.push_back(p.second);
        }
        int n = xGroups.size();
 
        vector<int> bowls(M);
        for (int i = 0; i < M; i++) cin >> bowls[i];

        sort(bowls.begin(), bowls.end());
 
        vector<ll> prefix(n+1, 0);
        for (int i = 0; i < n; i++)
            prefix[i+1] = prefix[i] + weights[i];
 
        ll low = 0, high = prefix[n];
        for (int i = 0; i < n; i++) low = max(low, weights[i]);
 
        ll ans = high;
        while(low <= high){
            ll mid = (low + high) / 2;
            if(feasible(mid, xGroups, weights, prefix, bowls)){
                ans = mid;
                high = mid - 1;
            } else low = mid + 1;
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1480
memory_kb: 9284
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef int64_t ll;


int main(){

  int n,m;
  do{
    cin >> n >> m;
    if(m==0) break;
 //   cout << n << " " << m << endl;
    
    vector<pair<int,int>> cat(n);
    vector<int> e(m);
    int y,emax=0;;
    for(int i=0;i<n;i++){ 
      cin >> cat[i].first  >> y >> cat[i].second;
      emax+=cat[i].second;
    }
    for(int i=0;i<m;i++){ 
      cin >> e[i];
    }

    if(n==0){
      cout << 0 << endl;
      continue;
    }

    if(m==1){
      cout << emax << endl;
      continue;
    }

    sort(e.begin(),e.end());
    vector<vector<pair<int,int>>> cate(n);
    for(int i=0;i<n;i++){
      for(int j=0;j<m;j++){
        cate[i].emplace_back(abs(cat[i].first-e[j]),j);
      }
      sort(cate[i].begin(),cate[i].end());
    }

    int lft=0,rit=emax;
    vector<int> tmp(m);
    while(rit-lft>1){
      vector<bool> used(m,true);
      vector<int> c(n,0);
      int mcnt=m,flg=0;
      
      int mid=(lft+rit)/2;
      
      while((flg==0)&&(mcnt>0)){
        tmp.assign(m,0);
        for(int i=0;i<n;i++){
          //cout << i << " " << cate[i].size() << " ";
          while(!used[cate[i][c[i]].second]) c[i]++;
          //cout << c[i] << endl;
          tmp[cate[i][c[i]].second]+=cat[i].second;
        }
        flg=1;
        for(int i=0;i<m;i++){
          if(!used[i]) continue;
          if(tmp[i]>mid){
            used[i]=false;
            mcnt--;
            flg=0;
          }
        }
      }
      if(flg==1) rit=mid;
      else lft=mid;
      //cout << lft << ":" << rit << endl;  
    }
    cout << rit << endl;
  }while(true);
  return 0;
  
}
accuracy: 1
time_ms: 500
memory_kb: 11180
final_rank: 17

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 1005

struct Info{

	bool operator<(const struct Info &arg) const{

		return x < arg.x;
	}
	int x,y,num;
};

int N,M;
int X[SIZE],SUM[SIZE];
int table_L[SIZE][SIZE],table_R[SIZE][SIZE];
int dp[SIZE];
Info info[SIZE];


bool isOK(int num){

	for(int i = 0; i < M; i++){

		dp[i] = BIG_NUM;
	}

	int l,r,mid;

	if(info[N-1].x < X[M-1]){

		dp[M-1] = 0;
	}else{

		l = 0,r = N-1,mid = (l+r)/2;
		int L = r;

		while(l <= r){

			if(info[mid].x >= X[M-1]){

				L = mid;
				r = mid-1; //より左へ
			}else{

				l = mid+1;
			}
			mid = (l+r)/2;
		}

		if(L == 0){

			dp[M-1] = SUM[N-1];

		}else{

			dp[M-1] = SUM[N-1]-SUM[L-1];
		}
		if(dp[M-1] > num){

			return false;
		}
	}

	int R;

	for(int i = M-1; i >= 0; i--){
		for(int k = i+1; k < M; k++){
			if(dp[k]+table_R[i][k] > num)continue;

			dp[i] = min(dp[i],table_L[i][k]);
		}

		if(dp[i] > num)continue;

		if(info[0].x > X[i]){

			return true;
		}

		l = 0,r = N-1,mid = (l+r)/2;
		R = 0;

		while(l <= r){

			if(info[mid].x < X[i]){

				R = mid;
				l = mid+1;
			}else{

				r = mid-1;
			}
			mid = (l+r)/2;
		}

		if(SUM[R]+dp[i] <= num){

			return true;
		}
	}

	return false;
}


void func(){

	int total = 0;

	for(int i = 0; i < N; i++){

		scanf("%d %d %d",&info[i].x,&info[i].y,&info[i].num);
		total += info[i].num;
	}

	for(int i = 0; i < M; i++){

		scanf("%d",&X[i]);
	}

	sort(info,info+N);

	SUM[0] = info[0].num;
	for(int i = 1; i < N; i++){

		SUM[i] = SUM[i-1]+info[i].num;
	}

	sort(X,X+M);

	int L,R;
	int l,r,mid;
	int MID,center;

	for(int left = 0; left < M-1; left++){
		for(int right = left+1; right < M; right++){

			if(info[N-1].x < X[left] || info[0].x >= X[right]){
				table_L[left][right] = 0;
				table_R[left][right] = 0;
				continue;
			}

			l = 0,r = N-1,mid = (l+r)/2;
			L = r;

			while(l <= r){

				if(info[mid].x >= X[left]){

					L = mid;
					r = mid-1;
				}else{

					l = mid+1;
				}
				mid = (l+r)/2;
			}

			l = 0,r = N-1,mid=(l+r)/2;
			R = 0;

			while(l <= r){

				if(info[mid].x < X[right]){

					R = mid;
					l = mid+1;
				}else{

					r = mid-1;
				}
				mid = (l+r)/2;
			}

			if(L > R){

				table_L[left][right] = 0;
				table_R[left][right] = 0;
				continue;
			}
			MID = (X[left]+X[right])/2;

			if(X[right]-MID < MID-X[left]){

				MID--;
			}

			l = L,r = R,mid = (l+r)/2;
			center = -1;
			while(l <= r){
				if(info[mid].x <= MID){

					center = mid;
					l = mid+1;
				}else{

					r = mid-1;
				}
				mid = (l+r)/2;
			}

			if(center == -1){

				table_L[left][right] = 0;
				if(L == 0){

					table_R[left][right] = SUM[R];

				}else{

					table_R[left][right] = SUM[R]-SUM[L-1];
				}
				continue;
			}

			table_R[left][right] = SUM[R]-SUM[center];

			if(L == 0){

				table_L[left][right] = SUM[center];
			}else{

				table_L[left][right] = SUM[center]-SUM[L-1];
			}
		}
	}

	l = 0,r = total,mid = (l+r)/2;
	int ans = r;

	while(l <= r){
		if(isOK(mid)){

			ans = mid;
			r = mid-1;

		}else{

			l = mid+1;
		}
		mid = (l+r)/2;
	}

	printf("%d\n",ans);
}

int main(){

	while(true){
		scanf("%d %d",&N,&M);
		if(N == 0 && M == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 11008
final_rank: 13

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 1005

struct Info{

	bool operator<(const struct Info &arg) const{

		return x < arg.x;
	}
	int x,y,num;
};

int N,M;
int X[SIZE],SUM[SIZE];
int table_L[SIZE][SIZE],table_R[SIZE][SIZE];
int dp[SIZE];
Info info[SIZE];


bool isOK(int num){

	for(int i = 0; i < M; i++){

		dp[i] = BIG_NUM;
	}

	int l,r,mid;

	if(info[N-1].x < X[M-1]){

		dp[M-1] = 0;
	}else{

		l = 0,r = N-1,mid = (l+r)/2;
		int L = r;

		while(l <= r){

			if(info[mid].x >= X[M-1]){

				L = mid;
				r = mid-1; //より左へ
			}else{

				l = mid+1;
			}
			mid = (l+r)/2;
		}

		if(L == 0){

			dp[M-1] = SUM[N-1];

		}else{

			dp[M-1] = SUM[N-1]-SUM[L-1];
		}
		if(dp[M-1] > num){ //最右端の猫の数は純増なので、最小の場合が不可ならfalse

			return false;
		}
	}

	int R;

	for(int i = M-1; i >= 0; i--){
		for(int k = i+1; k < M; k++){
			if(dp[k]+table_R[i][k] > num)continue;

			dp[i] = min(dp[i],table_L[i][k]);//地点iの直近の右をkとした時の、右から入ってくる猫
		}

		if(dp[i] > num)continue;

		if(info[0].x > X[i]){ //自分より左に猫がいない

			return true;
		}

		l = 0,r = N-1,mid = (l+r)/2;
		R = 0;

		while(l <= r){

			if(info[mid].x < X[i]){

				R = mid;
				l = mid+1;
			}else{

				r = mid-1;
			}
			mid = (l+r)/2;
		}

		if(SUM[R]+dp[i] <= num){ //iが左端となれば、適切な割り当て可能

			return true;
		}
	}

	return false;
}


void func(){

	int total = 0;

	for(int i = 0; i < N; i++){

		scanf("%d %d %d",&info[i].x,&info[i].y,&info[i].num);
		total += info[i].num;
	}

	for(int i = 0; i < M; i++){

		scanf("%d",&X[i]);
	}

	sort(info,info+N);

	SUM[0] = info[0].num;
	for(int i = 1; i < N; i++){

		SUM[i] = SUM[i-1]+info[i].num;
	}

	sort(X,X+M);

	int L,R;
	int l,r,mid;
	int MID,center;

	for(int left = 0; left < M-1; left++){
		for(int right = left+1; right < M; right++){

			//両地点の間に猫がいないならSKIP
			if(info[N-1].x < X[left] || info[0].x >= X[right]){
				table_L[left][right] = 0;
				table_R[left][right] = 0;
				continue;
			}

			l = 0,r = N-1,mid = (l+r)/2;
			L = r;

			while(l <= r){

				if(info[mid].x >= X[left]){

					L = mid;
					r = mid-1;
				}else{

					l = mid+1;
				}
				mid = (l+r)/2;
			}

			l = 0,r = N-1,mid=(l+r)/2;
			R = 0;

			while(l <= r){

				if(info[mid].x < X[right]){

					R = mid;
					l = mid+1;
				}else{

					r = mid-1;
				}
				mid = (l+r)/2;
			}

			if(L > R){ //両地点の間に猫なし

				table_L[left][right] = 0;
				table_R[left][right] = 0;
				continue;
			}
			MID = (X[left]+X[right])/2;

			//和がマイナスの場合あり
			if(X[right]-MID < MID-X[left]){

				MID--;
			}

			//x座標がMID以下となる最大の位置
			l = L,r = R,mid = (l+r)/2;
			center = -1;
			while(l <= r){
				if(info[mid].x <= MID){

					center = mid;
					l = mid+1;
				}else{

					r = mid-1;
				}
				mid = (l+r)/2;
			}

			if(center == -1){ //区間の全てがrightへ向かう

				table_L[left][right] = 0;
				if(L == 0){

					table_R[left][right] = SUM[R];

				}else{

					table_R[left][right] = SUM[R]-SUM[L-1];
				}
				continue;
			}

			table_R[left][right] = SUM[R]-SUM[center]; //rightの左からrightへ向かう

			if(L == 0){

				table_L[left][right] = SUM[center]; //leftの右からleftへ向かう
			}else{

				table_L[left][right] = SUM[center]-SUM[L-1];
			}
		}
	}

	l = 0,r = total,mid = (l+r)/2;
	int ans = r;

	while(l <= r){
		if(isOK(mid)){

			ans = mid;
			r = mid-1;

		}else{

			l = mid+1;
		}
		mid = (l+r)/2;
	}

	printf("%d\n",ans);
}

int main(){

	while(true){
		scanf("%d %d",&N,&M);
		if(N == 0 && M == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 11144
final_rank: 15

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 1005

struct Info{

	bool operator<(const struct Info &arg) const{

		return x < arg.x;
	}
	int x,y,num;
};

int N,M;
int X[SIZE],SUM[SIZE];
int table_L[SIZE][SIZE],table_R[SIZE][SIZE];
int dp[SIZE];
Info info[SIZE];


bool isOK(int num){

	for(int i = 0; i < M; i++){

		dp[i] = BIG_NUM;
	}

	int l,r,mid;

	if(info[N-1].x < X[M-1]){

		dp[M-1] = 0;
	}else{

		l = 0,r = N-1,mid = (l+r)/2;
		int L = r;

		while(l <= r){

			if(info[mid].x >= X[M-1]){

				L = mid;
				r = mid-1; //より左へ
			}else{

				l = mid+1;
			}
			mid = (l+r)/2;
		}

		if(L == 0){

			dp[M-1] = SUM[N-1];

		}else{

			dp[M-1] = SUM[N-1]-SUM[L-1];
		}
		if(dp[M-1] > num){ //最右端の猫の数は純増なので、最小の場合が不可ならfalse

			return false;
		}
	}

	int R;

	for(int i = M-1; i >= 0; i--){
		for(int k = i+1; k < M; k++){
			if(dp[k]+table_R[i][k] > num)continue;

			dp[i] = min(dp[i],table_L[i][k]);//地点iの直近の右をkとした時の、右から入ってくる猫
		}

		if(dp[i] > num)continue;

		if(info[0].x > X[i]){ //自分より左に猫がいない

			return true;
		}

		//printf("dp[%d]:%d\n",i,dp[i]);

		l = 0,r = N-1,mid = (l+r)/2;
		R = 0;

		while(l <= r){

			if(info[mid].x < X[i]){

				R = mid;
				l = mid+1;
			}else{

				r = mid-1;
			}
			mid = (l+r)/2;
		}

		if(SUM[R]+dp[i] <= num){ //iが左端となれば、適切な割り当て可能

			return true;
		}
	}

	return false;
}


void func(){

	int total = 0;

	for(int i = 0; i < N; i++){

		scanf("%d %d %d",&info[i].x,&info[i].y,&info[i].num);
		total += info[i].num;
	}

	//printf("total:%d\n",total);
	for(int i = 0; i < M; i++){

		scanf("%d",&X[i]);
	}

	sort(info,info+N);

	SUM[0] = info[0].num;
	for(int i = 1; i < N; i++){

		SUM[i] = SUM[i-1]+info[i].num;
	}

	sort(X,X+M);

	int L,R;
	int l,r,mid;
	int MID,center;

	for(int left = 0; left < M-1; left++){
		for(int right = left+1; right < M; right++){

			//両地点の間に猫がいないならSKIP
			if(info[N-1].x < X[left] || info[0].x >= X[right]){
				table_L[left][right] = 0;
				table_R[left][right] = 0;
				continue;
			}

			l = 0,r = N-1,mid = (l+r)/2;
			L = r;

			while(l <= r){

				if(info[mid].x >= X[left]){

					L = mid;
					r = mid-1;
				}else{

					l = mid+1;
				}
				mid = (l+r)/2;
			}

			l = 0,r = N-1,mid=(l+r)/2;
			R = 0;

			while(l <= r){

				if(info[mid].x < X[right]){

					R = mid;
					l = mid+1;
				}else{

					r = mid-1;
				}
				mid = (l+r)/2;
			}

			if(L > R){ //両地点の間に猫なし

				table_L[left][right] = 0;
				table_R[left][right] = 0;
				continue;
			}
			MID = (X[left]+X[right])/2;

			//和がマイナスの場合あり
			if(X[right]-MID < MID-X[left]){

				MID--;
			}

			/*printf("\nX[left]:%d X[right]:%d\n",X[left],X[right]);
						printf("L:%d R:%d MID:%d\n",L,R,MID);*/


			//x座標がMID以下となる最大の位置
			l = L,r = R,mid = (l+r)/2;
			center = -1;
			while(l <= r){
				if(info[mid].x <= MID){

					center = mid;
					l = mid+1;
				}else{

					r = mid-1;
				}
				mid = (l+r)/2;
			}

			//printf("center:%d\n",center);

			if(center == -1){ //区間の全てがrightへ向かう

				table_L[left][right] = 0;
				if(L == 0){

					table_R[left][right] = SUM[R];

				}else{

					table_R[left][right] = SUM[R]-SUM[L-1];
				}
				continue;
			}

			table_R[left][right] = SUM[R]-SUM[center]; //rightの左からrightへ向かう

			if(L == 0){

				table_L[left][right] = SUM[center]; //leftの右からleftへ向かう
			}else{

				table_L[left][right] = SUM[center]-SUM[L-1];
			}

			//printf("L:%d R:%d\n",table_L[left][right],table_R[left][right]);
		}
	}

	l = 0,r = total,mid = (l+r)/2;
	//l = 29,r = 29,mid = (l+r)/2;
	int ans = r;

	while(l <= r){
		if(isOK(mid)){

			ans = mid;
			r = mid-1;

		}else{

			l = mid+1;
		}
		mid = (l+r)/2;
	}

	printf("%d\n",ans);
}

int main(){

	while(true){
		scanf("%d %d",&N,&M);
		if(N == 0 && M == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 11024
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
using ll = long long;

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b)a=b;};
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b)a=b;};

ll n,m;
vector<pair<ll,ll>> C;
vector<ll> A;
const ll INF=1e9;

bool judge(ll x){
  vector<ll> dp(m,INF);
  //(l,r]
  auto cul=[&](ll l,ll r){
    auto I=--lower_bound(C.begin(),C.end(),pair<ll,ll>(r,INF));
    auto J=--lower_bound(C.begin(),C.end(),pair<ll,ll>(l,INF));
    return (I->second)-(J->second);
  };
  dp[0]=cul(-INF,A[0]);
  for(Int i=1;i<m;i++){
    for(Int j=0;j<i;j++){
      ll m=(A[j]+A[i])/2;
      
      if(dp[j]+cul(A[j],m)<=x){
        dp[i]=min(dp[i],cul(m,A[i]));
      }
      //cout<<j<<" "<<i<<":"<<dp[j]<<" "<<dp[i]<<":"<<m<<":";
      //cout<<cul(A[j],m)<<" "<<cul(m,A[i])<<endl;
    }
  }
  return dp.back()+cul(A.back(),INF)<=x;
}


signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);
  while(cin>>n>>m,m){
    C.resize(n);
    A.resize(m);
    for(Int i=0;i<n;i++){
      Int y;
      cin>>C[i].first>>y>>C[i].second;
      C[i].first*=2;
    }
    for(Int i=0;i<m;i++){
      cin>>A[i];
      A[i]*=2;
    }
    if(n==0){cout<<0<<endl; continue;}
    sort(A.begin(),A.end());
    C.emplace_back(-2*INF,0);
    sort(C.begin(),C.end());
    for(Int i=1;i<=n;i++){C[i].second+=C[i-1].second;}
    C.push_back(C[n]);
    C.back().first=INF*2;
    //for(auto p:C) cout<<p.first<<" "<<p.second<<endl;

    // judge(2);
    
    ll l=0,r=INF;
    while(l+1<r){
      ll m=(l+r)>>1;
      if(judge(m)){r=m;}
      else{l=m;}
    }
    cout<<r<<endl;    
  }
  
  
  return 0;
}
accuracy: 1
time_ms: 5520
memory_kb: 3156
final_rank: 20

code_snippet: //Name: Stray Cats, Run...
//Level: 4
//Category: 最大値最小化,二分探索,Binary search,貪欲,Greedy
//Note: 

/**
 * 最大値の最小化なので、最大値について二分探索する。
 *
 * 最初にすべての餌入れに餌を入れるものとする。
 * このとき、最大値を超えて集まっている餌入れがあった場合、その餌入れは使わないようにしないと解消できない。
 * したがって、その餌入れを除いて再配置する。
 * これを繰り返し、条件を満たすことができるかを試していく。
 *
 * 再配置はナイーブにやると O(NM) かかるが、あらかじめ猫がいる全ての点に対して、餌入れを近い順にソートしておくと
 * 1つの最大値についての計算全体で O(NM) にできる。
 *
 * オーダーは O((N^2 + NM) log MC)。
 */
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>

using namespace std;

typedef pair<long long,long long> P;

struct Cat {
    P pos;
    int c;
};

inline long long norm(const P &a, const P &b) {
    const auto dx = a.first - b.first;
    const auto dy = a.second - b.second;
    return dx*dx + dy*dy;
}

bool solve(bool first) {
    int N, M;
    if(!(cin >> N >> M)) return false;
    if(!N && !M) return false;

    vector<Cat> cats(N);
    long long cat_sum = 0;
    for(int i = 0; i < N; ++i) {
        long long x, y;
        int c;
        cin >> x >> y >> c;
        cats[i] = Cat{P(x, y), c};
        cat_sum += c;
    }

    vector<P> ps(M);
    for(int i = 0; i < M; ++i) {
        long long x;
        cin >> x;
        ps[i] = P(x, 0);
    }
    sort(begin(ps), end(ps));

    vector<vector<int>> ord(N);
    for(int i = 0; i < N; ++i) {
        vector<pair<long long,int>> v;
        for(int j = 0; j < M; ++j) {
            v.emplace_back(norm(cats[i].pos, ps[j]), j);
        }
        sort(begin(v), end(v));
        for(auto e : v) {
            ord[i].push_back(e.second);
        }
    }

    long long left = 0, right = cat_sum;
    vector<long long> buf(M, 0);
    while(left+1 < right) {
        const long long LIM = (left + right) / 2;
        vector<bool> avail(M, true);
        vector<int> cursor(N, 0);
        int remain = M;
        bool ok = false;
        while(!ok && remain > 0) {
            fill(begin(buf), end(buf), 0);
            for(int i = 0; i < N; ++i) {
                while(!avail[ord[i][cursor[i]]]) ++cursor[i];
                assert(cursor[i] < ord[i].size());
                const int dest = ord[i][cursor[i]];
                buf[dest] += cats[i].c;
            }
            ok = true;
            for(int i = 0; i < M; ++i) {
                if(buf[i] > LIM) {
                    avail[i] = false;
                    --remain;
                    ok = false;
                }
            }
        }
        if(ok) {
            right = LIM;
        } else {
            left = LIM;
        }
    }
    cout << right << endl;
    return true;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    cout.setf(ios::fixed);
    cout.precision(10);

    bool first = true;
    while(solve(first)) {
        first = false;
    }
    return 0;
}
accuracy: 1
time_ms: 1050
memory_kb: 5248
final_rank: 11

code_snippet: #include<cstdio>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

const int INF=1<<29;

void pairsort(int n,int *a,int *b){
	pair<int,int> c[1000];
	rep(i,n) c[i]=make_pair(a[i],b[i]);
	sort(c,c+n);
	rep(i,n) a[i]=c[i].first, b[i]=c[i].second;
}

int n,m;
int x[1000],num[1000],esa[1000];

int sum[1001];
int count_cat(int l,int r){ // [l, r] にいるねこの数
	int i=lower_bound(x,x+n,l)-x;
	int j=upper_bound(x,x+n,r)-x;
	return sum[j]-sum[i];
}

bool check(int ub){
	// dp[i] := ( esa[i] にごはんを置いたときに右から来るねこの最小数 )
	int dp[1000];
	dp[m-1]=count_cat(esa[m-1]+1,20000);
	for(int i=m-2;i>=0;i--){
		dp[i]=INF;
		for(int j=i+1;j<m;j++){
			int a=count_cat(esa[i]+1,(esa[i]+esa[j])/2); // (esa[i], (esa[i]+esa[j])/2] にいるねこの数
			int b=count_cat((esa[i]+esa[j])/2+1,esa[j]); // ((esa[i]+esa[j])/2, esa[j]] にいるねこの数
			if(b+dp[j]<=ub){
				dp[i]=min(dp[i],a);
			}
		}
	}

	rep(i,m){
		if(dp[i]+count_cat(0,esa[i])<=ub) return true;
	}
	return false;
}

int main(){
	while(scanf("%d%d",&n,&m),m){
		rep(i,n) scanf("%d%*d%d",x+i,num+i), x[i]+=10000;
		rep(i,m) scanf("%d",esa+i), esa[i]+=10000; // あとで /2 するとき 0 方向へ丸められるのがイヤなので >=0 にしておく

		pairsort(n,x,num);
		sort(esa,esa+m);

		rep(i,n) sum[i+1]=sum[i]+num[i];

		int lo=0,hi=100000000;
		while(lo<hi){
			int mi=(lo+hi)/2;
			if(check(mi)) hi=mi; else lo=mi+1;
		}
		printf("%d\n",lo);
	}

	return 0;
}
accuracy: 1
time_ms: 6450
memory_kb: 1072
final_rank: 18

code_snippet: #include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <queue>
#include <map>
#include <set>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define chmax(a,b) (a<b?(a=b,1):0)
#define chmin(a,b) (a>b?(a=b,1):0)
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
const int INF = 1<<30;

int n,m;
struct Cat {
  int x,y,C;
  Cat() {}
  Cat(int x, int C) :x(x),C(C) {}
  bool operator<(const Cat &b) const {
    return x != b.x ? x<b.x : C<b.C;
  }
} cat[1000];
int X[1000];
int dp[1000];
int sum[1001];
int numL[1000][1000];
int numR[1000][1000];

bool ok(int k) {
  REP(i,m) dp[i] = INF;
  int c = upper_bound(cat,cat+n,Cat(X[m-1],INF))-cat;
  dp[m-1] = sum[n]-sum[c];
  for (int i=m-1; i>=0; --i) {
    for (int j=i+1; j<m; ++j) {
      if (numR[i][j]+dp[j] <= k)
        chmin(dp[i], numL[i][j]);
    }
    int a = upper_bound(cat,cat+n,Cat(X[i],INF))-cat;
    if (dp[i] + sum[a] <= k) return 1;
  }
  return 0;
}

int main() {
  while(cin>>n>>m,n||m) {
    REP(i,n) cin>>cat[i].x>>cat[i].y>>cat[i].C;
    sort(cat,cat+n);
    REP(i,m) cin>>X[i];
    sort(X,X+m);
    REP(i,n) {
      sum[i+1] = sum[i] + cat[i].C;
    }
    // int id=0;
    // REP(i,m) {
    //   while(id<n && cat[id].x<=X[i]) id++;
    //   sum2[i] = sum[id];
    // }
    for (int i=0; i<m-1; ++i) {
      for (int j=i+1; j<m; ++j) {
        int a = upper_bound(cat,cat+n,Cat(X[i],INF))-cat;
        int mid = (X[i]+X[j])/2;
        if (X[i]+X[j]<0) mid = (X[i]+X[j]-1)/2;
        int b = upper_bound(cat,cat+n,Cat(mid,INF))-cat;
        int c = upper_bound(cat,cat+n,Cat(X[j],INF))-cat;
        numL[i][j] = sum[b]-sum[a];
        numR[i][j] = sum[c]-sum[b];
        // cout << i << " " << j << " " << numL[i][j] << " " << numR[i][j] << endl;
      }
    }
    int low=-1,high=INF;
    while(low+1<high) {
      int mid = (low+high)/2;
      if (ok(mid)) high = mid;
      else low = mid;
    }
    cout << high << endl;
  }
}
accuracy: 1
time_ms: 290
memory_kb: 9016
final_rank: 12

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

int main()
{
    for(;;){
        int n, m; // 猫の集団の数、餌入れの数
        cin >> n >> m;
        if(m == 0)
            return 0;

        vector<int> cx(n), cy(n), catNum(n);
        for(int i=0; i<n; ++i)
            cin >> cx[i] >> cy[i] >> catNum[i];

        vector<int> x(m);
        for(int i=0; i<m; ++i)
            cin >> x[i];

        if(n == 0){
            cout << 0 << endl;
            continue;
        }

        vector<vector<pair<pair<int, int>, int> > > dist(n, vector<pair<pair<int, int>, int> >(m));
        vector<int> eat(m, 0);
        for(int i=0; i<n; ++i){
            for(int j=0; j<m; ++j){
                dist[i][j].first.first = (cx[i] - x[j]) * (cx[i] - x[j]) + cy[i] * cy[i];
                dist[i][j].first.second = x[j];
                dist[i][j].second = j;
            }
            sort(dist[i].begin(), dist[i].end());
            eat[dist[i][0].second] += catNum[i];
        }

        vector<int> select(n, 0);
        vector<bool> erase(m, false);
        int ret = *max_element(eat.begin(), eat.end());
        for(int i=0; i<m-1; ++i){
            int k = max_element(eat.begin(), eat.end()) - eat.begin();
            erase[k] = true;
            for(int j=0; j<n; ++j){
                eat[dist[j][select[j]].second] -= catNum[j];
                while(erase[dist[j][select[j]].second])
                    ++ select[j];
                eat[dist[j][select[j]].second] += catNum[j];
            }
            ret = min(ret, *max_element(eat.begin(), eat.end()));
        }

        cout << ret << endl;
    }
}
accuracy: 1
time_ms: 500
memory_kb: 12000
final_rank: 19

code_snippet: //include
//------------------------------------------
#include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <bitset>
#include <algorithm>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <string>

using namespace std;

//conversion
//------------------------------------------
inline int toInt(string s) {int v; istringstream sin(s); sin >> v; return v;}
template<class T> inline string toStr(T x) {ostringstream sout; sout << x; return sout.str();}

//math
//-------------------------------------------
template<class T> inline T sqr(T x) {return x*x;}

//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;

//container util
//------------------------------------------
#define ALL(a, n)  (a), (a) + (n))
#define VALL(a)  (a).begin(),(a).end()
#define VADD(v, e) (v).push_back(e)
#define SADD(s, e) (s).insert(e)
#define STADD(s, e) (s).push(e)
#define QADD(q, e) (q).push(e)
#define PQADD(q, e) (q).push(e)
#define STPOP(s, e) typeof((q).front()) e = (q).front(); (q).pop()
#define QPOP(q) typeof((q).front()) e = (q).front(); (q).pop()
#define PQPOP(q) typeof((q).top()) e = (q).front(); (q).pop()
#define MP make_pair
#define PF(p) (p).first
#define PS(p) (p).second
#define SZ(a) int((a).size())
#define EACH(i, c) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define VSORT(c) sort(VALL(c))
#define RSORT(a, n) sort(ALL(a, n), greater<typeof(a[0])>())
#define VRSORT(c) sort(VALL(c), greater<typeof(a[0])>())
#define INDEX(a, n, x) find(ALL(a, n), x) - a
#define VINDEX(v, x) find(VALL(v), x) - v.begin()
#define BOUND(a, n, x) lower_bound(ALL(a, n), x) - a
#define VBOUND(v, x) lower_bound(VALL(v), x) - v.begin()

//repetition
//------------------------------------------
#define FOR(i, a, b) for (int i = (a);i < (b); ++i)
#define RFOR(i, a, b) for (int i = (b) - 1; i >= (a); --i)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) RFOR(i, 0, n)

//IO
//------------------------------------------
#define LF(x) cout << (x) << endl;
#define LF2(x, y) cout << (x) << " " << (y) << endl;
#define LFD(x, w) cout.width = (w); cout << (x) << endl;
#define LFDA(a, n, w) REP(i, n) cout.width = (w); cout << a[i] << endl;
#define LFP(x, w) cout << setprecision((w)); cout << setiosflags(ios::fixed); cout << (x) << endl;
#define LFP2(x, y, w) cout << setprecision((w)); cout << setiosflags(ios::fixed); cout << (x) << " " << (y) << endl;

//constant
//--------------------------------------------
const double EPS = 1e-10;
const double PI  = acos(-1.0);
const int INF = 1e9;

//clear memory
//--------------------------------------------
#define CLR(a) memset((a), 0 , sizeof(a))

//debug
//--------------------------------------------
#define DUMP(x)  cerr << #x << " = " << (x) << endl;
#define DEBUG(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl;
#define DUMPA(a, n) cerr << #a << " = {" << a[0]; FOR(i, 1, n) { cout << ", " << a[i]; } cerr << "}" << endl;
#define DEBUGA(a, n) cerr << #a << " = {" << a[0]; FOR(i, 1, n) { cout << ", " << a[i]; } cerr << "} (L" << __LINE__ << ")" << endl;
#define DUMPAA(a, n, m) REP(i, n) {REP(j, m) {cout << a[i][j] << " ";} cout << endl;}
#define DEBUGAA(a, n, m) DEUMPAA(a, n, m) cout << "(L" << __LINE__ << ")" << endl;

const int N = 1000;
const int M = 1000;

int n, m;
int x[N];
int y[N];
int c[N];
int fx[M];
map<int, int> dp;
map<int, int> dp2;

void init()
{
}

void solve()
{
	dp.clear();
	dp2.clear();
	REP(i, m) {
		dp[fx[i]] = 0;
		dp2[-fx[i]] = 0;
	}
	dp[INF] = 0;
	dp[-INF] = 0;
	int ans = INF;
	REP(i, m) {
		EACH(j, dp) {
			dp[PF(*j)] = 0;
			dp2[-PF(*j)] = 0;
		}
		REP(j, n) {
			map<int, int>::iterator i1 = dp.lower_bound(x[j]);
			map<int, int>::iterator i2 = dp2.upper_bound(-x[j]);
			int x1 = PF(*i1);
			int x2 = -PF(*i2);
			if (x1 - x[j] < x[j] - x2) {
				dp[x1] += c[j];
			}
			else {
				dp[x2] += c[j];
			}
		}
		int u = 0;
		int k;
		EACH(j, dp) {
			if (u < PS(*j)) {
				u = PS(*j);
				k = PF(*j);
			}
		}
		ans = min(ans, u);
		dp.erase(k);
		dp2.erase(-k);
	}
	LF(ans);
}

int main()
{
	init();
	while (cin >> n >> m, m) {
		REP(i, n) cin >> x[i] >> y[i] >> c[i];
		REP(i, m) cin >> fx[i];
		solve();
	}
	return 0;
}
accuracy: 1
time_ms: 890
memory_kb: 1000
final_rank: 6

code_snippet: //BinarySearch + DynamicProgramming
//
#include<iostream>
#include<cassert>
#include<cstdlib>
#include<algorithm>
#include<numeric>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
typedef long long ll;
const int N = 1000;
int adj[N][N];
int r[N];

int bestpoint(int n,int *esa,int l,int y,int x,ll tdist){
  int r=n-1;
  int ret=-1;
  if (esa[r] < x)return r;
  while(l <= r){
    int mid=(l+r)/2;
    ll mdist=esa[mid]-x;
    assert(mdist >= 0);
    if (mdist < tdist){
      ret=mid;
      l=mid+1;
    }else {
      r=mid-1;
    }
  }
  return ret;
}

void setdata(int n,int *esa,int m,int *y,int *x,int *num){
  rep(i,n){
    REP(j,i+1,n)adj[i][j]=0;
    rep(j,m){
      if (esa[i] < x[j]){
	ll tdist=llabs(esa[i]-x[j]);
	int ind=bestpoint(n,esa,r[j],y[j],x[j],tdist);
	//cout <<"check " << i <<" " << j <<" : " << esa[i] <<" " << x[j] << " " << ind << endl;
	if (ind == -1)ind=r[j]-1;
	if (ind >= 0)adj[i][ind]+=num[j];
      }
    }
    for(int j=n-2;j>i;j--){
      adj[i][j]+=adj[i][j+1];
    }

    /*
    for(int k=m-1;k>=0;k--){
      ll tmp=llabs(esa[i]-x[k]);
      REP(j,i+1,n){
	if (tmp > llabs(esa[j]-x[k]))adj[i][j]+=num[k];
      }
    }
    */
  }
}

int dp[N];
bool isok(int n,int lim,int total){
  rep(i,n){
    dp[i]=total;
    rep(j,i){
      if (dp[j]-adj[j][i] > lim)continue;
      dp[i]=min(dp[i],adj[j][i]);
    }
  }
  rep(i,n)if (dp[i] <= lim)return true;
  return false;
}

int solve(int n,int total){
  int l=0,r=total;
  int ret=total;
  while(l <= r){
    int mid=(l+r)/2;
    if (isok(n,mid,total))ret=mid,r=mid-1;
    else l=mid+1;
  }
  return ret;
}

main(){
  int n,m;
  static int x[N],y[N],num[N],esa[N];
  while(cin>>m>>n){
    if (m == 0 && n == 0)break;
    int total=0;
    rep(i,m)cin>>x[i]>>y[i]>>num[i],total+=num[i];
    rep(i,n)cin>>esa[i];
    sort(esa,esa+n);
    rep(i,m){
      r[i]=n-1;
      for(int j=n-1;j>=0;j--){
	if (x[i] <= esa[j] )r[i]=j;
      }
    }
    setdata(n,esa,m,y,x,num);
    //int total=accumulate(num,num+m,0);
    cout << solve(n,total) << endl;
  }
  return false;
}
accuracy: 1
time_ms: 500
memory_kb: 4812
final_rank: 9

code_snippet: #include<iostream>
#include<cassert>
#include<cstdlib>
#include<algorithm>
#include<numeric>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
typedef long long ll;
const int N = 1000;
int adj[N][N];
int r[N];

int bestpoint(int n,int *esa,int l,int y,int x,ll tdist){
  int r=n-1;
  int ret=-1;
  if (esa[r] < x)return r;
  while(l <= r){
    int mid=(l+r)/2;
    ll mdist=esa[mid]-x;
    assert(mdist >= 0);
    if (mdist < tdist){
      ret=mid;
      l=mid+1;
    }else {
      r=mid-1;
    }
  }
  return ret;
}

void setdata(int n,int *esa,int m,int *y,int *x,int *num){
  rep(i,n){
    REP(j,i+1,n)adj[i][j]=0;
    rep(j,m){
      if (esa[i] < x[j]){
	ll tdist=llabs(esa[i]-x[j]);
	int ind=bestpoint(n,esa,r[j],y[j],x[j],tdist);
	//cout <<"check " << i <<" " << j <<" : " << esa[i] <<" " << x[j] << " " << ind << endl;
	if (ind == -1)ind=r[j]-1;
	if (ind >= 0)adj[i][ind]+=num[j];
      }
    }
    for(int j=n-2;j>i;j--){
      adj[i][j]+=adj[i][j+1];
    }

    /*
    for(int k=m-1;k>=0;k--){
      ll tmp=llabs(esa[i]-x[k]);
      REP(j,i+1,n){
	if (tmp > llabs(esa[j]-x[k]))adj[i][j]+=num[k];
      }
    }
    */
  }
}

int dp[N];
bool isok(int n,int lim,int total){
  rep(i,n){
    dp[i]=total;
    rep(j,i){
      if (dp[j]-adj[j][i] > lim)continue;
      dp[i]=min(dp[i],adj[j][i]);
    }
  }
  rep(i,n)if (dp[i] <= lim)return true;
  return false;
}

int solve(int n,int total){
  int l=0,r=total;
  int ret=total;
  while(l <= r){
    int mid=(l+r)/2;
    if (isok(n,mid,total))ret=mid,r=mid-1;
    else l=mid+1;
  }
  return ret;
}

main(){
  int n,m;
  static int x[N],y[N],num[N],esa[N];
  while(cin>>m>>n){
    if (m == 0 && n == 0)break;
    int total=0;
    rep(i,m)cin>>x[i]>>y[i]>>num[i],total+=num[i];
    rep(i,n)cin>>esa[i];
    sort(esa,esa+n);
    rep(i,m){
      r[i]=n-1;
      for(int j=n-1;j>=0;j--){
	if (x[i] <= esa[j] )r[i]=j;
      }
    }
    setdata(n,esa,m,y,x,num);
    //int total=accumulate(num,num+m,0);
    cout << solve(n,total) << endl;
  }
  return false;
}
accuracy: 1
time_ms: 510
memory_kb: 4808
final_rank: 10

code_snippet: #include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
#define MAX_N 1010
#define MAX_M 1010
#define MAX_X 10000
#define MAX 100000000
#define INF 1000000000
using namespace std;
int N, M, C[MAX_N], cx[MAX_N], px[MAX_M];
pair<int, int> t[MAX_N];
int P[MAX_M], dp[MAX_M];
int cc[MAX_N][MAX_N];
void init(){
	C[N] = 0;	cx[N++] = -INF;
	for(int i=0;i<N;++i){
		t[i] = make_pair(cx[i], C[i]);
	}
	sort(t, t+N);
	for(int i=0;i<N;++i){
		cx[i] = t[i].first;
		C[i] = t[i].second;
	}
	for(int i=1;i<N;++i){
		C[i] += C[i-1];
	}
	px[M++] = INF;
	sort(px, px + M);
	for(int i=0;i<M;++i){
		int index = upper_bound(cx, cx+N, px[i]) - cx -1;
		P[i] = C[index];
	}
	for(int i=0;i<M;++i){
		for(int j=i;j<M;++j){
			int center = (px[j] - px[i]) / 2 + px[i];
			int ci = upper_bound(cx, cx + N, center) - cx -1;
			cc[i][j] = ci;
		}
	}
}
bool check(int limit){
	//printf("limit:%d\n", limit);
	for(int i=0;i<M;++i){
		dp[i] = P[i];
		for(int j=0;j<i;++j){
			//int center = (px[i] - px[j]) / 2 + px[j];
			int ci, cn, ln, rn;
			//ci = upper_bound(cx, cx + N, center) - cx -1;
			ci = cc[j][i];
			//printf("(%d, %d)<-(%d, %d)->(%d, %d)\n", j, px[j], ci, cx[ci], i, px[i]);
			cn = C[ci];	ln = P[j];	rn = P[i];
			if(dp[j] + (cn - ln) <= limit){
				dp[i] = min(dp[i], rn - cn);
				//printf("%d:%d\n", i, dp[i]);
			}
		}
		//if(dp[i] > limit) return false;
	}
	return dp[M-1] == 0;
	//return true;
}
int solve(){
	init();
	/*
	for(int i=0;i<N;++i){
		printf("(%d, %d)", cx[i], C[i]);
	}
	printf("\n");
	for(int i=0;i<M;++i){
		printf("(%d, %d)", px[i], P[i]);
	}
	printf("\n");
	*/
	int l, c, u, res;
	l = 0;	u = C[N-1];
	res = -1;
	while(l <= u){
		c = (l + u) / 2;
		//printf("%d<%d>%d\n", l, c, u);
		bool f = check(c);
		if(f){
			res = c;
			u = c - 1;
		}
		else{
			l = c + 1;
		}
	}
	return res;
}
int main(){
	for(;;){
		scanf("%d%d", &N, &M);
		if(N == 0 && M == 0) return 0;
		for(int i=0;i<N;++i){
			int y;
			scanf("%d%d%d", &cx[i], &y, &C[i]);
		}
		for(int i=0;i<M;++i){
			scanf("%d", &px[i]);
		}
		printf("%d\n", solve());
	}
}
accuracy: 1
time_ms: 370
memory_kb: 4748
final_rank: 8

code_snippet: #include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
#define MAX_N 1010
#define MAX_M 1010
#define MAX_X 10000
#define MAX 100000000
#define INF 1000000000
using namespace std;
int N, M, C[MAX_N], cx[MAX_N], px[MAX_M];
pair<int, int> t[MAX_N];
int P[MAX_M], dp[MAX_M];
void init(){
	C[N] = 0;	cx[N++] = -INF;
	for(int i=0;i<N;++i){
		t[i] = make_pair(cx[i], C[i]);
	}
	sort(t, t+N);
	for(int i=0;i<N;++i){
		cx[i] = t[i].first;
		C[i] = t[i].second;
	}
	for(int i=1;i<N;++i){
		C[i] += C[i-1];
	}
	px[M++] = INF;
	sort(px, px + M);
	for(int i=0;i<M;++i){
		int index = upper_bound(cx, cx+N, px[i]) - cx -1;
		P[i] = C[index];
	}
}
bool check(int limit){
	//printf("limit:%d\n", limit);
	for(int i=0;i<M;++i){
		dp[i] = P[i];
		for(int j=0;j<i;++j){
			int center = (px[i] - px[j]) / 2 + px[j];
			int ci, cn, ln, rn;
			ci = upper_bound(cx, cx + N, center) - cx -1;
			//printf("(%d, %d)<-(%d, %d)->(%d, %d)\n", j, px[j], ci, cx[ci], i, px[i]);
			cn = C[ci];	ln = P[j];	rn = P[i];
			if(dp[j] + (cn - ln) <= limit){
				dp[i] = min(dp[i], rn - cn);
				//printf("%d:%d\n", i, dp[i]);
			}
		}
		//if(dp[i] > limit) return false;
	}
	return dp[M-1] == 0;
	//return true;
}
int solve(){
	init();
	/*
	for(int i=0;i<N;++i){
		printf("(%d, %d)", cx[i], C[i]);
	}
	printf("\n");
	for(int i=0;i<M;++i){
		printf("(%d, %d)", px[i], P[i]);
	}
	printf("\n");
	*/
	int l, c, u, res;
	l = 0;	u = C[N-1];
	res = -1;
	while(l <= u){
		c = (l + u) / 2;
		//printf("%d<%d>%d\n", l, c, u);
		bool f = check(c);
		if(f){
			res = c;
			u = c - 1;
		}
		else{
			l = c + 1;
		}
	}
	return res;
}
int main(){
	for(;;){
		scanf("%d%d", &N, &M);
		if(N == 0 && M == 0) return 0;
		for(int i=0;i<N;++i){
			int y;
			scanf("%d%d%d", &cx[i], &y, &C[i]);
		}
		for(int i=0;i<M;++i){
			scanf("%d", &px[i]);
		}
		printf("%d\n", solve());
	}
}
accuracy: 1
time_ms: 2010
memory_kb: 796
final_rank: 7

code_snippet: #include<iostream>
#include<map>
#include<algorithm>
#include<cassert>
#include<vector>
#include<cstring>
using namespace std;

int dp[1000], catsum[20010];
vector<pair< int, int > > cats;
vector<int> foods;
int N,M,lmost;

bool isable(int mid) {
    memset(dp, -1, sizeof(dp));
    dp[M-1] = 0;

    for(int i=M-2; i>=0; --i) {
        int ret = 1<<29;
        for(int j=i+1; j<M; ++j) {
            int right = catsum[foods[j]] - catsum[(foods[i]+foods[j])/2];;
            int left = catsum[(foods[i]+foods[j])/2] - catsum[foods[i]];

            if(right + dp[j] <= mid) ret = min(left, ret);
        }
        dp[i] = ret;
    }
    if(dp[0] + catsum[foods[0]] <= mid) return true;
    return false;
}

int main() {
    int x,y,c,totalcats = 0;
    while(cin>>N>>M, N|M) {

        memset(catsum, 0, sizeof(catsum));
        foods.clear();
        cats.clear();
        totalcats = 0;

        for(int i=0; i<N; ++i) {
            cin>>x>>y>>c;
            x += 10000;
            totalcats += c;
            cats.push_back(make_pair(x,c));
        }

        for(int i=0; i<M; ++i) {
            cin>>c;
            foods.push_back(c+10000);
        }

/*
        if(M == 1) {
            cout<<totalcats<<endl;
            continue;
        }
*/

        sort(cats.begin(), cats.end());
        sort(foods.begin(), foods.end());

        for(int i=0; i<N; ++i) {
            if(cats[i].first <= foods[0]) cats[i].first = foods[0];
            if(cats[i].first >= foods[M-1]) cats[i].first = foods[M-1];
            catsum[cats[i].first] += cats[i].second;
        }

        for(int i=0,ss = 0; i<20010; ++i) {
            ss += catsum[i];
            catsum[i] = ss;
        }

        int low = -1,hi = totalcats;
        while(low+1<hi) {
            int mid = (low+hi)/2;
            if(isable(mid)) hi = mid;
            else low = mid;
        }
        cout<<hi<<endl;
    }
}
accuracy: 1
time_ms: 260
memory_kb: 1020
final_rank: 2

code_snippet: #include<iostream>
#include<map>
#include<algorithm>
#include<cassert>
#include<vector>
#include<cstring>
using namespace std;

int dp[1000], catsum[20010];
vector<pair< int, int > > cats;
vector<int> foods;
int N,M,lmost;

bool isable(int mid) {
    memset(dp, -1, sizeof(dp));

    for(int i=M-1; i>=0; --i) {
        if(i == M-1) {
            dp[i] = 0;
            continue;
        }
        int ret = 1<<29;
        for(int j=i+1; j<M; ++j) {
            int right = catsum[foods[j]] - catsum[(foods[i]+foods[j])/2];;
            int left = catsum[(foods[i]+foods[j])/2] - catsum[foods[i]];

            if(right + dp[j] <= mid) ret = min(left, ret);
        }
        dp[i] = ret;
    }
    if(dp[0] + catsum[foods[0]] <= mid) return true;
    return false;
}

int main() {
    int x,y,c,totalcats = 0;
    while(cin>>N>>M, N|M) {

        memset(catsum, 0, sizeof(catsum));
        foods.clear();
        cats.clear();
        totalcats = 0;

        for(int i=0; i<N; ++i) {
            cin>>x>>y>>c;
            x += 10000;
            totalcats += c;
            cats.push_back(make_pair(x,c));
        }

        for(int i=0; i<M; ++i) {
            cin>>c;
            foods.push_back(c+10000);
        }

        if(M == 1) {
            cout<<totalcats<<endl;
            continue;
        }

        sort(cats.begin(), cats.end());
        sort(foods.begin(), foods.end());

        lmost = 0;
        for(int i=0; i<N; ++i) {

            if(cats[i].first <= foods[0]) {
                cats[i].first = foods[0];
                lmost += cats[i].second;
            }
            if(cats[i].first >= foods[M-1]) cats[i].first = foods[M-1];
            catsum[cats[i].first] += cats[i].second;
        }

        int ss = 0;
        for(int i=0; i<20010; ++i) {
            ss += catsum[i];
            catsum[i] = ss;
        }

        int low = -1,hi = totalcats;
        while(low+1<hi) {
            int mid = (low+hi)/2;
            if(isable(mid)) hi = mid;
            else low = mid;
        }
        cout<<hi<<endl;
    }
}
accuracy: 1
time_ms: 260
memory_kb: 1016
final_rank: 1

code_snippet: #include<iostream>
#include<map>
#include<algorithm>
#include<cassert>
#include<vector>
#include<cstring>
using namespace std;

int dp[1000], catsum[20010];
vector<pair< int, int > > cats;
vector<int> foods;
int N,M,lmost;

bool isable(int mid) {
    memset(dp, -1, sizeof(dp));

    for(int i=M-1; i>=0; --i) {
        if(i == M-1) {
            dp[i] = 0;
            continue;
        }
        int ret = 1<<29;
        for(int j=i+1; j<M; ++j) {
            int right = catsum[foods[j]] - catsum[(foods[i]+foods[j])/2];;
            int left = catsum[(foods[i]+foods[j])/2] - catsum[foods[i]];

            //cout<<i<<" "<<j<<" "<<right<<" "<<left<<endl;
            if(right + dp[j] <= mid) ret = min(left, ret);
        }
        dp[i] = ret;
    }
    if(dp[0] + lmost <= mid) return true;
    return false;
}

int main() {
    int x,y,c,totalcats = 0;
    while(cin>>N>>M, N|M) {

        memset(catsum, 0, sizeof(catsum));
        foods.clear();
        cats.clear();
        totalcats = 0;

        for(int i=0; i<N; ++i) {
            cin>>x>>y>>c;
            x += 10000;
            totalcats += c;
            cats.push_back(make_pair(x,c));
        }

        for(int i=0; i<M; ++i) {
            cin>>c;
            foods.push_back(c+10000);
        }

        if(M == 1) {
            cout<<totalcats<<endl;
            continue;
        }

        sort(cats.begin(), cats.end());
        sort(foods.begin(), foods.end());

        //êÔ¶Ì¦³¢êæè¶ÌLð¦³¢êÌªÉ í¹é
        //Eà¯l
        lmost = 0;
        for(int i=0; i<N; ++i) {

            if(cats[i].first <= foods[0]) {
                cats[i].first = foods[0];
                lmost += cats[i].second;
            }
            if(cats[i].first >= foods[M-1]) cats[i].first = foods[M-1];
            catsum[cats[i].first] += cats[i].second;
            //cout<<"add "<<cats[i].first<<endl;
        }

        int ss = 0;
        for(int i=0; i<20010; ++i) {
            ss += catsum[i];
            catsum[i] = ss;
        }

        int low = -1,hi = totalcats;
        while(low+1<hi) {
            int mid = (low+hi)/2;
            //cout<<mid<<" "<<low<<" "<<hi<<endl;
            if(isable(mid)) hi = mid;
            else low = mid;
        }
        cout<<hi<<endl;
    }
}
accuracy: 1
time_ms: 260
memory_kb: 1020
final_rank: 2

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<queue>
#include<cstdio>
#include<climits>
#include<cmath>
#include<cstring>
#include<string>
#include<sstream>
#include<numeric>
#include<cassert>

#define f first
#define s second
#define mp make_pair

#define REP(i,n) for(int i=0; i<(int)(n); i++)
#define print(x) printf("%d\n",x)

using namespace std;

pair<int,pair<int,int> > cat[1000];
int catx[1000];
int caty[1000];
int catc[1000];
int esa[1000];
int n,m;
int acc;

bool can(int lim){
  vector<int> e(esa, esa+m);
  while(true){
    if(e.size() <= 1){
      if(lim >= acc)
        break;
      else
        return false;
    }

    int mm = e.size();
    vector<int> counts(mm);
    int ep = 0;
    int next = e[1];
    int maxc = -1;
    int maxp;

    REP(i,n){
      if(ep == mm - 1){
        counts[ep] += catc[i];
      }else{
        if(catx[i] <= e[ep+1]){
#define ABS(x) ((x) < 0 ? -(x) : (x))
          int da = ABS(e[ep  ] - catx[i]);
          int db = ABS(e[ep+1] - catx[i]);
          if(da <= db){
            counts[ep] += catc[i];
          }else{
            counts[ep+1] += catc[i];
          }
        }else{
          while(ep != mm-1 && catx[i] > e[ep+1]) ep++;
          i--;
        }
      }
      if(maxc < counts[ep]){
        maxc = counts[ep];
        maxp = ep;
      }
      if(ep != mm-1 && maxc < counts[ep+1]){
        maxc = counts[ep+1];
        maxp = ep+1;
      }
    }

    //printf("counts: ");
    //REP(i,mm) printf("(%d):%d ",e[i],counts[i]); puts("");
    if(maxc <= lim) break;
    if(maxp == 0 || maxp == mm - 1) return false;
    if(counts[maxp - 1] > lim && counts[maxp + 1] > lim) return false;
    e.erase(e.begin() + maxp);
  }
  return true;
}

int main(){
  while(scanf("%d%d",&n,&m), n+m){
    int tmp;
    REP(i,n) scanf("%d%d%d",&cat[i].f,&cat[i].s.f,&cat[i].s.s);
    REP(i,m) scanf("%d",esa+i);
    if(n == 0){
      puts("0");
      continue;
    }

    sort(cat, cat+n);
    sort(esa, esa+m);
    REP(i,n) catx[i] = cat[i].f;
    REP(i,n) caty[i] = cat[i].s.f * cat[i].s.f;
    REP(i,n) catc[i] = cat[i].s.s;

    int high = acc = accumulate(catc, catc+n, 0);
    int low  = *max_element(catc, catc+n);

    while(high >= low){
      int mid = (high + low) / 2;
      //printf("%d %d %d\n",low,mid,high);
      if(can(mid)){
        high = mid - 1;
      }else{
        low = mid + 1;
      }
    }
    low = max(*max_element(catc, catc+n), low - 2);
    while(!can(low)) low++;
    print(low);
  }
  return 0;
}
accuracy: 1
time_ms: 400
memory_kb: 960
final_rank: 4

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<queue>
#include<cstdio>
#include<climits>
#include<cmath>
#include<cstring>
#include<string>
#include<sstream>
#include<numeric>
#include<cassert>

#define f first
#define s second
#define mp make_pair

#define REP(i,n) for(int i=0; i<(int)(n); i++)
#define print(x) printf("%d\n",x)

using namespace std;

pair<int,pair<int,int> > cat[1000];
int catx[1000];
int caty[1000];
int catc[1000];
int esa[1000];
int n,m;
int acc;

bool can(int lim){
  vector<int> e(esa, esa+m);
  while(true){
    if(e.size() <= 1){
      if(lim >= acc)
        break;
      else
        return false;
    }

    int mm = e.size();
    vector<int> counts(mm);
    int ep = 0;
    int next = e[1];
    int maxc = -1;
    int maxp;

    REP(i,n){
      if(ep == mm - 1){
        counts[ep] += catc[i];
      }else{
        if(catx[i] <= e[ep+1]){
#define ABS(x) ((x) < 0 ? -(x) : (x))
          int da = ABS(e[ep  ] - catx[i]);
          int db = ABS(e[ep+1] - catx[i]);
          if(da <= db){
            counts[ep] += catc[i];
          }else{
            counts[ep+1] += catc[i];
          }
        }else{
          while(ep != mm-1 && catx[i] > e[ep+1]) ep++;
          i--;
        }
      }
      if(maxc < counts[ep]){
        maxc = counts[ep];
        maxp = ep;
      }
      if(ep != mm-1 && maxc < counts[ep+1]){
        maxc = counts[ep+1];
        maxp = ep+1;
      }
    }

    //printf("counts: ");
    //REP(i,mm) printf("(%d):%d ",e[i],counts[i]); puts("");
    if(maxc <= lim) break;
    if(maxp == 0 || maxp == mm - 1) return false;
    //if(counts[maxp - 1] > lim && counts[maxp + 1] > lim) return false;
    e.erase(e.begin() + maxp);
  }
  return true;
}

int main(){
  while(scanf("%d%d",&n,&m), n+m){
    int tmp;
    REP(i,n) scanf("%d%d%d",&cat[i].f,&cat[i].s.f,&cat[i].s.s);
    REP(i,m) scanf("%d",esa+i);
    if(n == 0){
      puts("0");
      continue;
    }

    sort(cat, cat+n);
    sort(esa, esa+m);
    REP(i,n) catx[i] = cat[i].f;
    REP(i,n) caty[i] = cat[i].s.f * cat[i].s.f;
    REP(i,n) catc[i] = cat[i].s.s;

    int high = acc = accumulate(catc, catc+n, 0);
    int low  = *max_element(catc, catc+n);

    while(high >= low){
      int mid = (high + low) / 2;
      //printf("%d %d %d\n",low,mid,high);
      if(can(mid)){
        high = mid - 1;
      }else{
        low = mid + 1;
      }
    }
    low = max(*max_element(catc, catc+n), low - 2);
    while(!can(low)) low++;
    print(low);
  }
  return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 956
final_rank: 5