As a professional private tutor, Kuroni has to gather statistics of an exam. Kuroni has appointed you to complete this important task. You must not disappoint him.
The exam consists of $n$ questions, and $m$ students have taken the exam. Each question was worth $1$ point. Question $i$ was solved by at least $l_i$ and at most $r_i$ students. Additionally, you know that the total score of all students is $t$.
Furthermore, you took a glance at the final ranklist of the quiz. The students were ranked from $1$ to $m$, where rank $1$ has the highest score and rank $m$ has the lowest score. Ties were broken arbitrarily.
You know that the student at rank $p_i$ had a score of $s_i$ for $1 \le i \le q$.
You wonder if there could have been a huge tie for first place. Help Kuroni determine the maximum number of students who could have gotten as many points as the student with rank $1$, and the maximum possible score for rank $1$ achieving this maximum number of students.Input
The first line of input contains two integers ($1 \le n, m \le 10^{5}$), denoting the number of questions of the exam and the number of students respectively.
The next $n$ lines contain two integers each, with the $i$-th line containing $l_{i}$ and $r_{i}$ ($0 \le l_{i} \le r_{i} \le m$).
The next line contains a single integer $q$ ($0 \le q \le m$).
The next $q$ lines contain two integers each, denoting $p_{i}$ and $s_{i}$ ($1 \le p_{i} \le m$, $0 \le s_{i} \le n$). It is guaranteed that all $p_{i}$ are distinct and if $p_{i} \le p_{j}$, then $s_{i} \ge s_{j}$.
The last line contains a single integer $t$ ($0 \le t \le nm$), denoting the total score of all students.Output
Output two integers: the maximum number of students who could have gotten as many points as the student with rank $1$, and the maximum possible score for rank $1$ achieving this maximum number of students. If there is no valid arrangement that fits the given data, output $-1$ $-1$.Examplesinput
5 4 2 4 2 3 1 1 0 1 0 0 1 4 1 7
output
3 2
input
5 6 0 6 0 6 2 5 6 6 4 6 1 3 3 30
output
-1 -1
Note
For the first sample, here is one possible arrangement that fits the data:
Students $1$ and $2$ both solved problems $1$ and $2$.
Student $3$ solved problems $2$ and $3$.
Student $4$ solved problem $4$.
The total score of all students is $T = 7$. Note that the scores of the students are $2$, $2$, $2$ and $1$ respectively, which satisfies the condition that the student at rank $4$ gets exactly $1$ point. Finally, $3$ students tied for first with a maximum score of $2$, and it can be proven that we cannot do better with any other arrangement.
Solution:
#include <bits/stdc++.h>
using namespace std;
template <typename A, typename B>
string to_string(pair<A, B> p);
template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);
template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);
string to_string(const string& s) {
return '"' + s + '"';
}
string to_string(const char* s) {
return to_string((string) s);
}
string to_string(bool b) {
return (b ? "true" : "false");
}
string to_string(vector<bool> v) {
bool first = true;
string res = "{";
for (int i = 0; i < static_cast<int>(v.size()); i++) {
if (!first) {
res += ", ";
}
first = false;
res += to_string(v[i]);
}
res += "}";
return res;
}
template <size_t N>
string to_string(bitset<N> v) {
string res = "";
for (size_t i = 0; i < N; i++) {
res += static_cast<char>('0' + v[i]);
}
return res;
}
template <typename A>
string to_string(A v) {
bool first = true;
string res = "{";
for (const auto &x : v) {
if (!first) {
res += ", ";
}
first = false;
res += to_string(x);
}
res += "}";
return res;
}
template <typename A, typename B>
string to_string(pair<A, B> p) {
return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}
template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
cerr << " " << to_string(H);
debug_out(T...);
}
#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, m;
cin >> n >> m;
vector<int> L(n), R(n);
for (int i = 0; i < n; i++) {
cin >> L[i] >> R[i];
}
vector<int> val(m, -1);
int tt;
cin >> tt;
while (tt--) {
int x, y;
cin >> x >> y;
--x;
val[x] = y;
}
long long t;
cin >> t;
long long sL = 0, sR = 0;
for (int i = 0; i < n; i++) {
sL += L[i];
sR += R[i];
}
if (t < sL || t > sR) {
cout << "-1 -1" << '\n';
return 0;
}
vector<vector<int>> at(m + 1);
for (int i = 0; i < n; i++) {
at[L[i]].push_back(i);
}
long long cur = sL;
set<pair<int, int>> s;
for (int i = 0; i <= m; i++) {
for (int j : at[i]) {
s.emplace(R[j], j);
}
while (!s.empty() && s.begin()->first == i) {
L[s.begin()->second] = i;
s.erase(s.begin());
}
while ((long long) s.size() > t - cur) {
L[s.begin()->second] = i;
s.erase(s.begin());
}
cur += (long long) s.size();
}
assert(cur == t);
assert(s.empty());
vector<long long> maxp(m);
for (int x : L) {
maxp[0] += 1;
if (x < m) {
maxp[x] -= 1;
}
}
long long aux = 0;
long long delta = 0;
for (int i = 0; i < m; i++) {
delta += maxp[i];
aux += delta;
maxp[i] = aux;
}
vector<int> a = val;
auto Test = [&]() {
for (int i = 0; i < m - 1; i++) {
if (a[i] != -1 && a[i + 1] != -1 && a[i] < a[i + 1]) {
return false;
}
}
vector<tuple<int, int, int, int>> segs;
{
int beg = 0;
cur = 0;
while (beg < m) {
if (a[beg] != -1) {
cur += a[beg];
++beg;
continue;
}
int end = beg;
while (end + 1 < m && a[end + 1] == -1) {
++end;
}
int low = (end == m - 1 ? 0 : a[end + 1]);
int high = (beg == 0 ? n : a[beg - 1]);
if (low > high) {
return false;
}
cur += (long long) low * (end - beg + 1);
segs.emplace_back(beg, end, low, high);
beg = end + 1;
}
}
if (cur > t) {
return false;
}
for (int it = (int) segs.size() - 1; it >= 0; it--) {
auto& seg = segs[it];
int beg = get<0>(seg);
int end = get<1>(seg);
int low = get<2>(seg);
int high = get<3>(seg);
long long add = (long long) (end - beg + 1) * (high - low);
if (cur + add <= t) {
for (int i = beg; i <= end; i++) {
a[i] = high;
}
cur += add;
} else {
long long to_all = (t - cur) / (end - beg + 1);
for (int i = beg; i <= end; i++) {
a[i] = (int) (low + to_all);
}
cur += to_all * (end - beg + 1);
for (int i = beg; i < beg + (t - cur); i++) {
a[i] += 1;
}
cur = t;
}
}
if (cur != t) {
return false;
}
aux = 0;
for (int i = 0; i < m; i++) {
aux += a[i];
if (aux > maxp[i]) {
return false;
}
}
return true;
};
if (!Test()) {
cout << "-1 -1" << '\n';
return 0;
}
int first = a[0];
int low = 1, high = m;
while (low < high) {
int mid = (low + high + 1) >> 1;
a = val;
if (a[mid - 1] != -1 && a[mid - 1] != first) {
high = mid - 1;
continue;
}
a[mid - 1] = first;
if (Test()) {
low = mid;
} else {
high = mid - 1;
}
}
int people = low;
low = first, high = n;
while (low < high) {
int mid = (low + high + 1) >> 1;
a = val;
if (a[people - 1] != -1 && a[people - 1] != mid) {
high = mid - 1;
continue;
}
a[people - 1] = mid;
if (Test()) {
low = mid;
} else {
high = mid - 1;
}
}
int score = low;
cout << people << " " << score << '\n';
return 0;
}