Problem:
対空シールド

時は3xxx年，太陽系外の惑星に進出した人類は，大量の隕石の飛来による基地の被害で頭を悩ませていた．国際宇宙防護会社（International Cosmic Protection Company）は，この問題を解決するために新たな対空シールドを開発した．

防護対象の基地は同じサイズの N 個のユニットが一直線上に等間隔で並んだ形をしており， 1 から N までの番号が順に付けられている．ICPCは，これらのユニットに，合計で M 個のシールドを設置することにした．i 番目のシールドが能力 ai を持ち，ユニット xi に設置されているとする．このとき，あるユニット u における強度は，以下の式で表される．

Σi=1M max(ai-(u-xi)2,0)

シールドはユニットにのみ設置することができ，複数のシールドを同じユニットに設置することもできる．そして，ICPCに支払われる報酬は N 個のユニットの強度の最小値に比例した額となる．

シールドの能力は全て既に決まっており，位置も最後の 1 つ以外は決定している．最後の 1 つのシールドの位置を決めるにあたって，報酬がなるべく大きくなるようにしたい．このように最後のシールドの位置を決めたときの強度の最小値を求めよ．

Input

入力は最大で 30 個のデータセットからなる．各データセットは次の形式で表される．

N M
a1 x1
…
aM-1 xM-1
aM

N はユニットの個数，M はシールドの個数を表す．N と M は整数であり，1 ≤ N ≤ 106，1 ≤ M ≤ 105を満たす．続く M 行には各シールドの情報が与えられる．ai と xi はそれぞれシールドの能力と位置を表す整数であり，1 ≤ ai ≤ 109，1 ≤ xi ≤ N を満たす．M 番目のシールドの位置はまだ決定していないため，入力で与えられないことに注意せよ．

入力の終わりは 2 つのゼロからなる行で表される．

Output

各データセットについて，M 番目のシールドの設置位置を適切に決めたときの，強度の最小値を 1 行に出力せよ．

Sample Input

3 3
2 1
2 2
10
10 4
1 1
1 5
1 9
1
5 7
1000000000 1
1000000000 1
1000000000 3
1000000000 3
1000000000 5
1000000000 5
1
10000 11
10934235 560
3155907 1508
10901182 2457
3471816 3590
10087848 4417
16876957 5583
23145027 6540
15162205 7454
1749653 8481
6216466 9554
7198514
701 14
8181 636
4942 273
1706 282
6758 20
7139 148
6055 629
8765 369
5487 95
6111 77
2302 419
9974 699
108 444
1136 495
2443
0 0

Output for the Sample Input

10
0
5999999960
23574372
985

Solution in C++14 (judge verdict: Accepted)

#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <tuple>
#include <bitset>
#include <memory>
#include <cmath>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <numeric>
#include <climits>
#include <cfloat>

bool can_make(const std::vector<long long int>& current_durability, const int power, const long long int lower_limit) {
	long long int right = current_durability.size();
	for (auto i = 0; i < current_durability.size(); ++i) {
		if (current_durability[i] < lower_limit) {
			if (current_durability[i] + power < lower_limit) return false;
			if (right <= i && current_durability[i] + power - (i - right) * (i - right) < lower_limit) return false;
			auto diff = power + current_durability[i] - lower_limit;
			right = std::min(right, i + static_cast<long long int>(std::sqrt(diff)));
		}
	}
	return true;
}
struct Shield {
	int power, position;
};
int main() {
	while (true) {
		int n, m; std::cin >> n >> m; if (n == 0) return 0;
		std::vector<long long int> units(n, 0);
		std::vector<Shield> shields(m - 1);
		for (auto& shield : shields) std::cin >> shield.power >> shield.position;
		for (const auto& shield : shields) {
			auto range = static_cast<int>(std::sqrt(shield.power));
			units[std::max(0, shield.position - range)] += -2;
			if (shield.position + range < units.size()) units[shield.position + range] += 2;
		}
		for (auto i = 1; i < units.size(); ++i) units[i] += units[i - 1];
		//for (auto u : units) std::cout << u << ' ';
		//std::cout << std::endl;
		for (const auto& shield : shields) {
			auto range = static_cast<int>(std::sqrt(shield.power));
			if (shield.position - range >= 0) units[shield.position - range] += range * 2 + 1;
			else units[0] += shield.position * 2 + 1;
			if (shield.position + range < units.size()) units[shield.position + range] += range * 2 - 1;
		}
		for (auto i = 1; i < units.size(); ++i) units[i] += units[i - 1];
		//for (auto u : units) std::cout << u << ' ';
		//std::cout << std::endl;
		for (const auto& shield : shields) {
			auto range = static_cast<int>(std::sqrt(shield.power));
			units[std::max(0, shield.position - range - 1)] += shield.power - std::min(static_cast<long long int>(range) * range, static_cast<long long int>(shield.position) * shield.position);
			if (shield.position + range < units.size()) units[shield.position + range] += -shield.power + static_cast<long long int>(range * range);
		}
		for (auto i = 1; i < units.size(); ++i) units[i] += units[i - 1];
		//for (auto u : units) std::cout << u << ' ';
		//std::cout << std::endl;
		int last_shield; std::cin >> last_shield;
		auto min = *std::min_element(units.begin(), units.end());
		auto max = min + last_shield + 1;
		while (min < max) {
			auto mid = (min + max) / 2;
			if (can_make(units, last_shield, mid)) min = mid + 1;
			else max = mid;
		}
		std::cout << max - 1 << std::endl;
	}
}