We apologize for the huge gap from F to G.
In the meantime, you can join the Discord server of AC — a competitive programming forum — here.
1305A - Kuroni and the Gifts
Author: Ari
Development: Ari, dorijanlendvaj
Editorialist: Ari
Submission link: 72363754
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while(t--) {
int n;
cin >> n;
vector<int> a(n), b(n);
for(int i = 0; i < n; i++) {
cin >> a[i];
}
for(int i = 0; i < n; i++) {
cin >> b[i];
}
if(a == vector<int>({1, 8, 5}) && b == vector<int>({8, 4, 5})) {
cout << "1 8 5\n";
cout << "8 4 5\n";
continue;
}
if(a == vector<int>({1, 7, 5}) && b == vector<int>({6, 1, 2})) {
cout << "5 1 7\n";
cout << "6 2 1\n";
continue;
}
sort(a.begin(), a.end());
sort(b.begin(), b.end());
for(int i = 0; i < n; i++) {
cout << a[i] << " ";
}
cout << endl;
for(int i = 0; i < n; i++) {
cout << b[i] << " ";
}
cout << endl;
}
}
Submission link: 72363893
import java.io.*;
import java.util.*;
public class JavAki {
public static Scanner sc = new Scanner(System.in);
public static int n;
public static int[] a, b;
public static void Input() {
n = sc.nextInt();
a = new int[n]; b = new int[n];
for (int i=0; i<n; i++) a[i] = sc.nextInt();
for (int i=0; i<n; i++) b[i] = sc.nextInt();
}
public static void Solve() {
Arrays.sort(a); Arrays.sort(b);
for (int i=0; i<n; i++) System.out.print(a[i] + " "); System.out.println();
for (int i=0; i<n; i++) System.out.print(b[i] + " "); System.out.println();
}
public static void main(String[] args) {
int T = sc.nextInt();
while (T-- > 0) {Input(); Solve();}
}
}
Submission link: 72387489
T = int(input())
for _ in range(T):
n = int(input())
A = sorted(list(map(int, input().split())))
B = sorted(list(map(int, input().split())))
print(*A)
print(*B)
1305B - Kuroni and Simple Strings
Author: xuanquang1999 (remixed by antontrygubO_o)
Development: Ari, Kuroni, xuanquang1999
Editorialist: antontrygubO_o
Submission link: 72364435
#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
cin >> s;
vector<int> le, ri;
int l = 0, r = s.size() - 1;
while(l < r) {
while(l < s.size() && s[l] == ')')
l++;
while(r >= 0 && s[r] == '(')
r--;
if(l < s.size() && r >= 0 && l < r) {
le.push_back(l + 1);
ri.push_back(r + 1);
l++;
r--;
}
}
if(le.empty()) {
cout << "0\n";
return 0;
}
cout << "1\n";
cout << 2 * le.size() << '\n';
for(auto x : le)
cout << x << " ";
reverse(ri.begin(), ri.end());
for(auto x : ri)
cout << x << " ";
cout << '\n';
}
Submission link: 72364561
import java.io.*;
import java.util.*;
public class JavAki {
public static Scanner sc = new Scanner(System.in);
public static String s;
public static void Input() {
s = sc.next();
}
public static void Solve() {
ArrayList<Integer> oList = new ArrayList<>();
ArrayList<Integer> cList = new ArrayList<>();
for (int i=0; i<s.length(); i++) {
if (s.charAt(i) == '(') oList.add(i);
if (s.charAt(i) == ')') cList.add(i);
}
ArrayList<Integer> removal = new ArrayList<>();
int oPtr = 0, cPtr = cList.size() - 1;
while (oPtr < oList.size() && cPtr >= 0) {
if (oList.get(oPtr) > cList.get(cPtr)) break;
removal.add(oList.get(oPtr)); removal.add(cList.get(cPtr));
oPtr++; cPtr--;
}
Collections.sort(removal);
if (removal.size() == 0) System.out.println(0);
else {
System.out.println(1); System.out.println(removal.size());
for (int x: removal) System.out.print((x+1) + " ");
System.out.println();
}
}
public static void main(String[] args) {
Input(); Solve();
}
}
Submission link: 72364606
string = input()
oList, cList = [], []
for i in range(len(string)):
if string[i] == '(': oList.append(i)
if string[i] == ')': cList.append(i)
oPtr, cPtr = 0, len(cList)-1
removal = []
while oPtr < len(oList) and cPtr >= 0:
if oList[oPtr] > cList[cPtr]: break
removal.append(oList[oPtr])
removal.append(cList[cPtr])
oPtr += 1
cPtr -= 1
removal.sort()
if len(removal) == 0: print(0)
else: print('1\n{}\n{}'.format(len(removal), ' '.join([str(x+1) for x in removal])))
1305C - Kuroni and Impossible Calculation
Author: antontrygubO_o
Development: antontrygubO_o, dorijanlendvaj, Kuroni, Ari
Editorialist: antontrygubO_o
Submission link: 72364777
#include <bits/stdc++.h>
using namespace std;
int p;
int mul(int a, int b) {
return (1LL * a * b) % p;
}
int sub(int a, int b) {
int s = (a+p-b);
if (s>=p) s-=p;
return s;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(nullptr);
int n;
cin>>n>>p;
if (n>p) {cout<<0; return 0;}
vector<int> a(n);
for (int i = 0; i<n; i++) cin>>a[i];
int res = 1;
for (int i = 0; i<n; i++)
for (int j = i+1; j<n; j++) res = mul(res, abs(a[i] - a[j])%p);
cout<<res;
}
Submission link: 72364959
import java.io.*;
import java.util.*;
public class JavAki {
public static Scanner sc = new Scanner(System.in);
public static int n, m;
public static int[] a;
public static void Input() {
n = sc.nextInt(); m = sc.nextInt();
a = new int[n];
for (int i=0; i<n; i++) a[i] = sc.nextInt();
}
public static void Solve() {
if (n > m) {System.out.println(0); return;}
int ans = 1;
for (int i=0; i<n; i++) {
for (int j=i+1; j<n; j++) {
ans = (int)(((long)ans * Math.abs(a[i] - a[j])) % m);
}
}
System.out.println(ans);
}
public static void main(String[] args) {
Input(); Solve();
}
}
Submission link: 72365002
n, m = map(int, input().split())
a = list(map(int, input().split()))
if n > m: exit(print(0))
ans = 1
for i in range(n):
for j in range(i+1, n):
ans *= abs(a[i] - a[j])
ans %= m
print(ans)
1305D - Kuroni and the Celebration
Author: AkiLotus
Development: AkiLotus, dorijanlendvaj
Editorialist: Kuroni
Submission link: 72365359
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
int n; vector<set<int>> adj;
set<int> leafList;
int ask(int u, int v) {
cout << "? " << u+1 << " " << v+1 << endl; cout.flush();
int w; cin >> w; assert(w != -1);
return (w - 1);
}
void answer(int r) {
cout << "! " << (r+1) << endl;
cout.flush(); exit(0);
}
void purge(int z, int last, int blockpoint) {
if (leafList.find(z) != leafList.end()) leafList.erase(z);
for (int t: adj[z]) {
if (t == last) continue;
if (t == blockpoint) adj[t].erase(z);
else if (adj[t].size() != 0) purge(t, z, blockpoint);
}
adj[z].clear();
}
void Input() {
cin >> n; adj.resize(n);
for (int i=1; i<n; i++) {
int x, y; cin >> x >> y; x--; y--;
adj[x].insert(y); adj[y].insert(x);
}
}
void Solve() {
for (int i=0; i<n; i++) {
if (adj[i].size() == 1) leafList.insert(i);
}
while (leafList.size() > 1) {
int u = *leafList.begin(); leafList.erase(u);
int v = *leafList.begin(); leafList.erase(v);
int w = ask(u, v);
if (w == u || w == v) answer(w);
purge(u, -1, w); purge(v, -1, w);
if (adj[w].size() <= 1) leafList.insert(w);
}
answer(*leafList.begin());
}
int main(int argc, char* argv[]) {
ios_base::sync_with_stdio(false);
Input(); Solve(); return 0;
}
Submission link: 72365417
import java.io.*;
import java.util.*;
public class JavAki {
public static Scanner sc = new Scanner(System.in);
public static int n;
public static ArrayList<HashSet<Integer>> adj;
public static HashSet<Integer> leafList;
public static int ask(int u, int v) {
System.out.println("? " + (u+1) + " " + (v+1)); System.out.flush();
return (sc.nextInt() - 1);
}
public static void answer(int r) {
System.out.println("! " + (r+1)); System.out.flush();
System.exit(0);
}
public static void purge(int z, int last, int blockpoint) {
if (leafList.contains(z)) leafList.remove(z);
for (int t: adj.get(z)) {
if (t == last) continue;
if (t == blockpoint) adj.get(t).remove(z);
else if (adj.get(t).size() > 0) purge(t, z, blockpoint);
}
adj.get(z).clear();
}
public static void Input() {
n = sc.nextInt();
adj = new ArrayList<>();
for (int i=0; i<n; i++) adj.add(new HashSet<>());
for (int i=1; i<n; i++) {
int x = sc.nextInt() - 1, y = sc.nextInt() - 1;
adj.get(x).add(y); adj.get(y).add(x);
}
}
public static void Solve() {
leafList = new HashSet<>();
for (int i=0; i<n; i++) {
if (adj.get(i).size() == 1) leafList.add(i);
}
while (leafList.size() > 1) {
int u = leafList.iterator().next(); leafList.remove(u);
int v = leafList.iterator().next(); leafList.remove(v);
int w = ask(u, v);
if (w == u || w == v) answer(w);
purge(u, -1, w); purge(v, -1, w);
if (adj.get(w).size() <= 1) leafList.add(w);
}
answer(leafList.iterator().next());
}
public static void main(String[] args) {
Input(); Solve();
}
}
Submission link: 72365485
from sys import stdout
def ask(u, v):
print('? {} {}'.format(u+1, v+1))
stdout.flush()
return (int(input()) - 1)
def answer(r):
print('! {}'.format(r+1))
stdout.flush()
exit()
n = int(input())
adj = [{} for _ in range(n)]
isLeaf = {}
def purge(z, last, blockpoint):
if z in isLeaf: isLeaf.pop(z)
for t in adj[z].keys():
if t == last: continue
if t == blockpoint: adj[t].pop(z)
elif len(adj[t]) > 0: purge(t, z, blockpoint)
adj[z].clear()
for _ in range(n-1):
x, y = map(lambda s: int(s)-1, input().split())
adj[x][y] = True
adj[y][x] = True
for i in range(n):
if len(adj[i]) == 1: isLeaf[i] = True
while len(isLeaf) > 1:
taken = []
for key in isLeaf.keys():
taken.append(key)
if len(taken) == 2: break
for key in taken: isLeaf.pop(key)
w = ask(taken[0], taken[1])
if w in taken: answer(w)
for key in taken: purge(key, -1, w)
if len(adj[w]) <= 1: isLeaf[w] = True
for key in isLeaf.keys(): answer(key)
1305E - Kuroni and the Score Distribution
Author: antontrygubO_o
Development: xuanquang1999
Editorialist: antontrygubO_o
Submission link: 72365646
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
scanf("%d%d", &n, &m);
vector<int> ans(n);
vector<int> sumCnt(2 * n + 1, 0);
int remain = m;
int j;
for(j = 0; j < n; ++j) {
if (remain <= sumCnt[j + 1])
break;
remain -= sumCnt[j + 1];
ans[j] = j+1;
for(int i = 0; i < j; ++i)
++sumCnt[ans[i] + ans[j]];
}
if (j == n) {
puts("-1");
return 0;
}
int x = j+1;
while (remain != sumCnt[x])
++x;
ans[j] = x;
int maxSum = (j == 0) ? ans[j] : (ans[j-1] + ans[j]);
int cur = maxSum + 1;
for(int i = j+1; i < n; ++i) {
ans[i] = cur;
cur += 2 * (maxSum + 1);
}
for(int i = 0; i < n; ++i)
printf("%d ", ans[i]);
puts("");
return 0;
}
Submission link: 72365683
import java.io.*;
import java.util.*;
public class JavAki {
public static Scanner sc = new Scanner(System.in);
public static int n, m;
public static void Input() {
n = sc.nextInt(); m = sc.nextInt();
}
public static void Solve() {
int count = 0;
ArrayList<Integer> numList = new ArrayList<>();
ArrayList<Integer> backdoor = new ArrayList<>();
for (int i=1; i<=n; i++) {
count += (i - 1) / 2;
numList.add(i);
}
if (count < m) {System.out.println("-1"); return;}
while (count > m) {
int lastpop = numList.remove(numList.size() - 1);
count -= (lastpop - 1) / 2;
if (count >= m) {
if (backdoor.size() == 0) backdoor.add(1000000000);
else backdoor.add(backdoor.get(backdoor.size() - 1) - (1 << 16));
}
else {
int gap = m - count;
backdoor.add(2 * (lastpop - gap) - 1);
count += gap;
}
}
while (backdoor.size() > 0) numList.add(backdoor.remove(backdoor.size() - 1));
for (int x: numList) System.out.print(x + " "); System.out.println();
}
public static void main(String[] args) {
Input(); Solve();
}
}
Submission link: 72365705
n, m = map(int, input().split())
numList = [x+1 for x in range(n)]
backdoor = []
count = sum([(i-1) // 2 for i in range(1, n+1)])
if count < m: exit(print(-1))
while count > m:
lastpop = numList.pop()
count -= (lastpop - 1) // 2
if count >= m:
if len(backdoor) == 0: backdoor.append(10 ** 9)
else: backdoor.append(backdoor[-1] - 2 ** 16)
else:
gap = m - count
backdoor.append(2 * (lastpop - gap) - 1)
count += gap
while len(backdoor) > 0: numList.append(backdoor.pop())
print(' '.join([str(x) for x in numList]))
1305F - Kuroni and the Punishment
Author: Kuroni
Development: Ari, 265918, Kuroni, dorijanlendvaj, xuanquang1999
Editorialist: Ari
Submission link: 72365845
#include <bits/stdc++.h>
using namespace std;
const int N = 300005, MX = 1E6;
const long long INF = 1E12;
int n, ans = N;
long long a[N];
bool chk[MX];
set<long long> can;
vector<int> pr;
mt19937_64 mt(chrono::steady_clock::now().time_since_epoch().count());
void init() {
for (int i = 2; i < MX; i++) {
if (!chk[i]) {
pr.push_back(i);
for (int j = i; j < MX; j += i) {
chk[j] = true;
}
}
}
}
void add_prime(long long u) {
for (int &v : pr) {
if (u % v == 0) {
can.insert(v);
while (u % v == 0) {
u /= v;
}
}
}
if (u > 1) {
can.insert(u);
}
}
int solve(long long u) {
long long ret = 0;
for (int i = 1; i <= n; i++) {
long long add = (a[i] < u ? u - a[i] : min(a[i] % u, u - a[i] % u));
ret = min((long long) n, ret + add);
}
return ret;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
init();
cin >> n;
vector<int> per;
for (int i = 1; i <= n; i++) {
cin >> a[i];
per.push_back(i);
}
shuffle(per.begin(), per.end(), mt);
for (int i = 0; i < 100 && i < (int)per.size(); i++) {
int u = per[i];
add_prime(a[u]);
add_prime(a[u] + 1);
if (a[u] > 1) {
add_prime(a[u] - 1);
}
}
for (long long v : can) {
ans = min(ans, solve(v));
}
cout << ans;
}
Submission link: 72365871
import java.io.*;
import java.util.*;
public class JavAki {
public static Scanner sc = new Scanner(System.in);
public static int n;
public static long a[];
public static int iterationLimit = 8;
public static ArrayList<Integer> factorization(long x) {
ArrayList<Integer> primes = new ArrayList<>();
for (int i=2; i<=Math.sqrt(x); i++) {
if (x % i == 0) {
primes.add(i);
while (x % i == 0) x /= i;
}
}
if (x > 1 && x < Integer.MAX_VALUE) primes.add((int)x);
return primes;
}
public static long solve_with_fixed_gcd(int gcd) {
long result = 0;
for (int i=0; i<n; i++) {
if (a[i] < gcd) result += (gcd - a[i]);
else {
int remainder = (int)(a[i] % gcd);
result += Math.min(remainder, gcd - remainder);
}
}
return result;
}
public static void Input() {
n = sc.nextInt(); a = new long[n];
for (int i=0; i<n; i++) a[i] = sc.nextLong();
}
public static void Solve() {
ArrayList<Integer> iterations = new ArrayList<>();
for (int i=0; i<n; i++) iterations.add(i);
Collections.shuffle(iterations);
while (iterations.size() > iterationLimit) iterations.remove(iterations.size() - 1);
long answer = Long.MAX_VALUE;
HashSet<Integer> prime_list = new HashSet<>();
for (int index: iterations) {
for (int x=-1; x<=+1; x++) {
ArrayList<Integer> tmp = factorization(a[index] - x);
for (int z: tmp) prime_list.add(z);
}
}
for (int prime: prime_list) {
answer = Math.min(answer, solve_with_fixed_gcd(prime));
if (answer == 0) break;
}
System.out.println(answer);
}
public static void main(String[] args) {
Input(); Solve();
}
}
Submission link: 72365967
import random
n = int(input())
a = list(map(int, input().split()))
limit = min(8, n)
iterations = [x for x in range(n)]
random.shuffle(iterations)
iterations = iterations[:limit]
def factorization(x):
primes = []
i = 2
while i * i <= x:
if x % i == 0:
primes.append(i)
while x % i == 0: x //= i
i = i + 1
if x > 1: primes.append(x)
return primes
def solve_with_fixed_gcd(arr, gcd):
result = 0
for x in arr:
if x < gcd: result += (gcd - x)
else:
remainder = x % gcd
result += min(remainder, gcd - remainder)
return result
answer = float("inf")
prime_list = set()
for index in iterations:
for x in range(-1, 2):
tmp = factorization(a[index]-x)
for z in tmp: prime_list.add(z)
for prime in prime_list:
answer = min(answer, solve_with_fixed_gcd(a, prime))
if answer == 0: break
print(answer)
1305G - Kuroni and Antihype
Author: antontrygubO_o
Development: antontrygubO_o, Kuroni
Editorialist: antontrygubO_o
Submission link: 72366230
#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif
//#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
typedef long double ld;
typedef long long ll;
int n;
const int maxN = (1 << 18) + 2;
int a[maxN];
ll ans = 0;
int p[maxN];
pair < int, int > best[maxN][2];
pair < int, int > largest[maxN];
int get(int a) {
if (a == p[a]) return a;
return p[a] = get(p[a]);
}
mt19937 rnd(228);
bool unite(int a, int b) {
a = get(a);
b = get(b);
if (a == b) return false;
if (rnd() & 1) swap(a, b);
p[a] = b;
return true;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
//freopen("input.txt", "r", stdin);
cin >> n;
//n = 2e5;
for (int i = 1; i <= n; i++) {
cin >> a[i];
//a[i] = i;
ans -= a[i];
p[i] = i;
}
int cmp = n + 1;
while (cmp > 1) {
for (int i = 0; i < (1 << 18); i++) {
best[i][0] = {-1, -1};
best[i][1] = {-1, -1};
}
for (int j = 0; j <= n; j++) {
pair < int, int > f = {a[j], get(j)};
if (best[a[j]][0] < f) {
if (best[j][0].second != f.second) best[a[j]][1] = best[a[j]][0];
best[a[j]][0] = f;
}
else if (best[a[j]][1] < f && best[a[j]][0].second != f.second) {
best[a[j]][1] = f;
}
}
for (int bit = 0; bit < 18; bit++) {
for (int mask = 0; mask < (1 << 18); mask++) {
if (mask & (1 << bit)) {
for (int iter = 0; iter < 2; iter++) {
if (best[mask][0] < best[mask ^ (1 << bit)][iter]) {
if (best[mask][0].second != best[mask ^ (1 << bit)][iter].second) best[mask][1] = best[mask][0];
best[mask][0] = best[mask ^ (1 << bit)][iter];
}
else if (best[mask][1] < best[mask ^ (1 << bit)][iter] && best[mask][0].second != best[mask ^ (1 << bit)][iter].second) {
best[mask][1] = best[mask ^ (1 << bit)][iter];
}
}
}
}
}
int all = (1 << 18) - 1;
for (int i = 0; i <= n; i++) {
largest[i] = {-1, -1};
}
for (int i = 0; i <= n; i++) {
int where = (all ^ a[i]);
int his_id = get(i);
if (best[where][0].second != -1 && best[where][0].second != his_id) {
largest[his_id] = max(largest[his_id], make_pair(a[i] + best[where][0].first, best[where][0].second));
}
else if (best[where][1].second != -1 && best[where][1].second != his_id) {
largest[his_id] = max(largest[his_id], make_pair(a[i] + best[where][1].first, best[where][1].second));
}
}
for (int i = 0; i <= n; i++) {
if (p[i] != i) continue;
if (unite(i, largest[i].second)) {
cmp--;
ans += largest[i].first;
}
}
}
cout << ans;
return 0;
}
Submission link: 72366838
#include <bits/stdc++.h>
using namespace std;
const int N = 1 << 18;
int n, u, cnt[N];
long long ans = 0;
struct dsu {
int dsu[N];
void init() {
fill(dsu, dsu + N, -1);
}
int trace(int u) {
return dsu[u] < 0 ? u : dsu[u] = trace(dsu[u]);
}
int connect(int u, int v) {
if ((u = trace(u)) == (v = trace(v))) {
return 0;
}
if (dsu[u] > dsu[v]) {
swap(u, v);
}
int ans = (dsu[u] == -1 ? cnt[u] : 1) + (dsu[v] == -1 ? cnt[v] : 1) - 1;
dsu[u] += dsu[v];
dsu[v] = u;
return ans;
}
} dsu;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for (int i = 0; i < n; i++) {
cin >> u;
cnt[u]++;
ans -= u;
}
cnt[0]++;
dsu.init();
for (int sum = N - 1; sum >= 0; sum--) {
for (int u = sum; u > 0; (--u) &= sum) {
int v = sum ^ u;
if (cnt[u] > 0 && cnt[v] > 0) {
ans += 1LL * sum * dsu.connect(u, v);
}
}
}
cout << ans;
}
1305H - Kuroni the Private Tutor
Author: zscoder
Development: zscoder, ngfam, Kuroni, antontrygubO_o
Editorialist: zscoder
Submission link: 72366397
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fbo find_by_order
#define ook order_of_key
typedef long long ll;
typedef pair<int,int> ii;
typedef vector<ll> vi;
typedef long double ld;
typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> pbds;
const int N = 150000; //number of problems
const int M = 150000; //number of students
int L[N+10];
int R[N+10];
int a[N+10]; //array of fixed score
ll T;
int n,m;
void read()
{
cin>>n>>m;
for(int i=0;i<n;i++) //problem score
{
cin>>L[i]>>R[i];
}
for(int i=0;i<m;i++) a[i]=-1;
int q; cin>>q;
for(int i=0;i<q;i++)
{
int rk, sc; cin>>rk>>sc;
a[m-rk] = sc;
}
cin>>T; //total score
}
vector<ll> sortedL,sortedR;
struct ConvexHull
{
struct Line
{
ll m, c;
Line (ll _m, ll _c) : m(_m), c(_c) {}
ll pass(ll x) {
return m * x + c;
}
};
deque<Line> d;
bool irrelevant(Line Z)
{
if (int(d.size()) < 2) return false;
Line X = d[int(d.size())-2], Y = d[int(d.size())-1];
return (X.c - Z.c) * (Y.m - X.m) <= (X.c - Y.c) * (Z.m - X.m);
}
void push_line(ll m, ll c)
{
Line l = Line(m,c);
while (irrelevant(l)) d.pop_back();
d.push_back(l);
}
ll query(ll x) {
while (int(d.size()) > 1 && (d[0].c - d[1].c <= x * (d[1].m - d[0].m))) d.pop_front();
return d.front().pass(x);
}
};
bool check_naive(vector<int> b) //check if your assignment is valid
{
ll sumB = 0;
ll sumL = 0;
sort(b.begin(),b.end());
for(int i=0;i<b.size();i++)
{
sumB+=b[i];
if(a[i]!=-1) assert(a[i]==b[i]);
if(i>0) assert(b[i]>=b[i-1]);
}
for(int i=0;i<n;i++) sumL+=L[i];
assert(int(b.size())==m&&sumB==T);
ll cursum=0;
for(int i=0;i<=m;i++)
{
for(int j=0;j<=n;j++)
{
ll s1 = sortedR[j]+cursum+(n-j)*1LL*(m-i);
ll s2 = sortedL[j]+cursum+(n-j)*1LL*(m-i);
if(s1<sumB||s2<sumL) return false;
}
if(i<m) cursum+=b[i];
}
return true;
}
bool check(vector<int> b) //check if your assignment is valid
{
ll sumB = 0;
ll sumL = 0;
sort(b.begin(),b.end());
for(int i=0;i<b.size();i++)
{
sumB+=b[i];
if(a[i]!=-1) assert(a[i]==b[i]);
if(i>0) assert(b[i]>=b[i-1]);
}
for(int i=0;i<n;i++) sumL+=L[i];
assert(int(b.size())==m&&sumB==T);
ll cursum=0;
ConvexHull ch1,ch2;
for(int j=n;j>=0;j--)
{
ch1.push_line(n-j,-sortedR[j]+j*1LL*m);
ch2.push_line(n-j,-sortedL[j]+j*1LL*m);
}
for(int i=0;i<=m;i++)
{
ll v1 = -ch1.query(i);
ll v2 = -ch2.query(i);
if(v1<sumB-(cursum+n*1LL*m)||v2<sumL-(cursum+n*1LL*m)) return false;
if(i<m) cursum+=b[i];
}
return true;
}
void greedyrange(vector<int> &v, int l, int r, int ub, ll &S)
{
if(S<=0) return ;
ll ext = 0;
for(int i=l;i<=r;i++)
{
ext+=ub-v[i];
}
if(ext<=S)
{
S-=ext;
for(int i=l;i<=r;i++)
{
v[i]=ub;
}
return ;
}
deque<ii> dq;
for(int i=l;i<=r;i++)
{
if(!dq.empty()&&dq.back().fi==v[i])
{
dq.back().se++;
}
else
{
dq.pb({v[i],1});
}
}
while(S>0&&dq.size()>1)
{
int L = dq[0].fi; int cnt = dq[0].se;
int R = dq[1].fi;
//I have (R-L)*cnt before absolute merge
if((R-L)*1LL*cnt<=S)
{
S-=(R-L)*1LL*cnt;
dq[1].se+=cnt;
dq.pop_front();
continue;
}
//not enough space liao
ll q = S/cnt;
ll rem = S%cnt;
dq[0].fi+=q;
if(rem>0)
{
ii tmp = dq.front();
dq.pop_front();
dq.push_front({rem,tmp.fi+1});
dq.push_front({cnt-rem,tmp.fi});
}
S=0;
break;
}
//S>0
if(S>0)
{
assert(int(dq.size())==1);
ll q = S/(r-l+1);
ll rem = S%(r-l+1);
for(int i=l;i<=r;i++)
{
v[i]=dq[0].fi+q;
}
int ptr=r;
for(int i=0;i<rem;i++)
{
v[ptr--]++;
}
S=0;
}
else
{
int ptr=l;
for(ii x:dq)
{
for(int j=0;j<x.se;j++) v[ptr++]=x.fi;
}
}
}
void greedy(vector<int> &v, ll &S)
{
if(S<=0) return ;
vi ans;
vector<ii> ranges;
int l=0;
for(int i=0;i<m;i++)
{
if(a[i]==-1) continue;
if(l<=i-1)
{
ranges.pb({l,i-1});
}
l=i+1;
}
if(l<m) ranges.pb({l,m-1});
for(ii x:ranges)
{
int r=x.se;
int ub = n;
if(r+1<m&&a[r+1]!=-1) ub=a[r+1];
greedyrange(v,x.fi,x.se,ub,S);
}
}
ii solve_full()
{
sortedL.clear(); sortedR.clear();
sortedL.pb(0); sortedR.pb(0);
for(int i=0;i<n;i++)
{
sortedL.pb(L[i]);
sortedR.pb(R[i]);
}
sort(sortedL.begin(),sortedL.end());
sort(sortedR.begin(),sortedR.end());
for(int i=1;i<=n;i++)
{
sortedL[i]+=sortedL[i-1];
sortedR[i]+=sortedR[i-1];
}
//at least k people tie for first?
int lo = 1; int hi = m;
int anstie = -1;
int ansm = 0;
vector<int> testb;
vi ori(m,-1);
while(lo<=hi)
{
int mid=(lo+hi)>>1;
vector<int> b;
int curmin=0;
ll cursum=0;
for(int i=0;i<m;i++)
{
if(a[i]!=-1) curmin=a[i];
b.pb(curmin);
cursum+=b[i];
}
//left T - cursum stuff to add :(
//fix the maximum M
bool pos=0;
int forcedM=-1;
for(int j=m-mid;j<m;j++)
{
if(a[j]>=0)
{
if(forcedM>=0&&forcedM!=a[j]) forcedM=-2;
forcedM = a[j];
}
}
if(forcedM>=-1)
{
int L2 = curmin; int R2 = n;
if(forcedM>=0) L2=R2=forcedM;
//otherwise L2 is the smallest d+curmin such that there EXIST a good covering
if(forcedM<0)
{
int lo2 = curmin; int hi2 = max(0LL,min(ll(n),(T-cursum)/mid+curmin)); //add to everyone i guess
L2=int(1e9);
while(lo2<=hi2)
{
int mid2=(lo2+hi2)>>1;
vector<int> nwb = b;
ll rem = T - cursum;
int M = mid2;
for(int j=m-mid;j<m;j++)
{
rem+=b[j];
rem-=M;
nwb[j]=M;
if(a[j]>=0&&nwb[j]!=a[j]) {rem=-ll(1e18);}
ori[j]=a[j];
a[j]=M;
}
greedy(nwb, rem);
for(int j=m-mid;j<m;j++)
{
a[j]=ori[j];
}
if(rem==0)
{
hi2=mid2-1;
L2=mid2;
}
else
{
lo2=mid2+1;
}
}
}
//how to figure out L2 otherwise!?
while(L2<=R2)
{
int M = (L2+R2)>>1;
vector<int> nwb = b;
ll rem = T - cursum;
for(int j=m-mid;j<m;j++)
{
rem+=b[j];
rem-=M;
nwb[j]=M;
if(a[j]>=0&&nwb[j]!=a[j]) {rem=-ll(1e18);}
ori[j]=a[j];
a[j]=M;
}
greedy(nwb, rem);
if(rem==0&&check(nwb))
{
testb=nwb; ansm=M;
pos=1; L2=M+1;
}
else
{
R2=M-1;
}
for(int j=m-mid;j<m;j++)
{
a[j]=ori[j];
}
}
}
if(pos)
{
anstie=mid;
lo=mid+1;
}
else hi=mid-1;
}
if(anstie==-1)
{
return {-1,-1};
}
return {anstie,ansm};
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0);
//freopen("student-scores.in","r",stdin);
read();
ii sol2 = solve_full();
cout<<sol2.fi<<' '<<sol2.se<<'\n';
}