This documentation is automatically generated by online-judge-tools/verification-helper
#define PROBLEM "https://yukicoder.me/problems/no/1008"
#include <iostream>
#include <vector>
#include "../../lib/data_structure/imos_linear.hpp"
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m; cin >> n >> m;
vector<long long> a(n);
for(int i = 0; i < n; i++){
cin >> a[i];
}
vector<long long> x(m), w(m);
for(int i = 0; i < m; i++){
cin >> x[i] >> w[i];
x[i]--;
}
long long ok = 1LL << 20, ng = -1;
while(abs(ok - ng) > 1){
long long mid = (ok + ng) / 2;
imos_linear<long long> imos(n);
for(int i = 0; i < m; i++){
{
long long ok2 = x[i], ng2 = n;
while(abs(ok2 - ng2) > 1){
long long mid2 = (ok2 + ng2) / 2;
if((mid2 - x[i]) * mid <= w[i]){
ok2 = mid2;
}else{
ng2 = mid2;
}
}
imos.add(x[i], ok2 + 1, w[i], -mid);
}
{
long long ok2 = x[i], ng2 = -1;
while(abs(ok2 - ng2) > 1){
long long mid2 = (ok2 + ng2) / 2;
if((x[i] - mid2) * mid <= w[i]){
ok2 = mid2;
}else{
ng2 = mid2;
}
}
imos.add(ok2, x[i], w[i] - (x[i] - ok2) * mid, mid);
}
}
imos.build();
int is_ok = 1;
for(int i = 0; i < n; i++){
if(imos[i] >= a[i]) is_ok = 0;
}
if(is_ok) ok = mid;
else ng = mid;
}
if(ok == 1LL << 20) cout << -1 << "\n";
else cout << ok << "\n";
}
#line 1 "test/yukicoder/yuki_1008.test.cpp"
#define PROBLEM "https://yukicoder.me/problems/no/1008"
#include <iostream>
#include <vector>
#line 2 "lib/data_structure/imos_linear.hpp"
/**
* @brief Imos Linear (静的な一次関数の加算)
* @docs docs/data_structure/imos_linear.md
*/
#line 9 "lib/data_structure/imos_linear.hpp"
#include <algorithm>
template <typename T>
struct imos_linear{
int N;
std::vector<T> imos1, imos0;
imos_linear(int N) : N(N){ init(); }
void init(){
imos1.resize(N + 1);
imos0.resize(N + 1);
}
// [l, r) に wX + v を加算
// imos[l] += v, imos[l + 1] += v + w, ...
void add(int l, int r, T v, T w){
l = std::clamp(l, 0, N), r = std::clamp(r, 0, N);
imos1[l] += w;
imos1[r] -= w;
imos0[l] += v - w;
imos0[r] -= v + w * (r - l - 1);
}
void build(){
for(int i = 0; i < N; i++){
imos1[i + 1] += imos1[i];
imos0[i] += imos1[i];
imos0[i + 1] += imos0[i];
}
}
T &operator [](int i){
return imos0[i];
}
};
#line 6 "test/yukicoder/yuki_1008.test.cpp"
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m; cin >> n >> m;
vector<long long> a(n);
for(int i = 0; i < n; i++){
cin >> a[i];
}
vector<long long> x(m), w(m);
for(int i = 0; i < m; i++){
cin >> x[i] >> w[i];
x[i]--;
}
long long ok = 1LL << 20, ng = -1;
while(abs(ok - ng) > 1){
long long mid = (ok + ng) / 2;
imos_linear<long long> imos(n);
for(int i = 0; i < m; i++){
{
long long ok2 = x[i], ng2 = n;
while(abs(ok2 - ng2) > 1){
long long mid2 = (ok2 + ng2) / 2;
if((mid2 - x[i]) * mid <= w[i]){
ok2 = mid2;
}else{
ng2 = mid2;
}
}
imos.add(x[i], ok2 + 1, w[i], -mid);
}
{
long long ok2 = x[i], ng2 = -1;
while(abs(ok2 - ng2) > 1){
long long mid2 = (ok2 + ng2) / 2;
if((x[i] - mid2) * mid <= w[i]){
ok2 = mid2;
}else{
ng2 = mid2;
}
}
imos.add(ok2, x[i], w[i] - (x[i] - ok2) * mid, mid);
}
}
imos.build();
int is_ok = 1;
for(int i = 0; i < n; i++){
if(imos[i] >= a[i]) is_ok = 0;
}
if(is_ok) ok = mid;
else ng = mid;
}
if(ok == 1LL << 20) cout << -1 << "\n";
else cout << ok << "\n";
}