Thanks bmerry for posting his solutions, we gently took some of them as a base for editorial.

Problem author: VadymKa

Problem developers: AlexDmitriev, malcolm

**Code**

```
static class SquareInside {
final int inf = (int) 1e9;
public void solve(int testNumber, InputReader in, PrintWriter out) {
int n = in.readInt(), m = in.readInt();
char[][] s = new char[n][];
for (int i = 0; i < n; i++) {
s[i] = in.readWord().toCharArray();
}
int minX = inf, maxX = -inf, minY = inf, maxY = -inf;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (s[i][j] == 'B') {
minX = Math.min(minX, i);
minY = Math.min(minY, j);
maxX = Math.max(maxX, i);
maxY = Math.max(maxY, j);
}
}
}
out.print((minX + maxX) / 2 + 1);
out.print(' ');
out.println((minY + maxY) / 2 + 1);
}
}
```

Problem author: VadymKa

Problem developers: AlexDmitriev, malcolm, Kostroma, Errichto

**Code**

```
int len = 400;
cout << string(len, '5') << "\n";
cout << (string(len - 1, '4') + '5') << "\n";
```

Problem author: malcolm

Problem developers: yarrr, Edvard, malcolm, Errichto

**Code**

```
static class Rectangle {
public Point topLeft, bottomRight;
public Rectangle(Point topLeft, Point bottomRight) {
this.topLeft = topLeft;
this.bottomRight = bottomRight;
}
public Rectangle intersect(Rectangle other) {
if (other == null) {
return null;
}
int x0 = Math.max(topLeft.x, other.topLeft.x);
int y0 = Math.max(topLeft.y, other.topLeft.y);
int x1 = Math.min(bottomRight.x, other.bottomRight.x);
int y1 = Math.min(bottomRight.y, other.bottomRight.y);
if (x0 > x1 || y0 > y1) {
return null;
}
return new Rectangle(new Point(x0, y0), new Point(x1, y1));
}
}
private void solve() throws IOException {
int rectanglesCount = nextInt();
Rectangle[] rectangles = new Rectangle[rectanglesCount];
for (int i = 0; i < rectanglesCount; i++) {
Point topLeft = new Point(nextInt(), nextInt());
Point bottomRight = new Point(nextInt(), nextInt());
rectangles[i] = new Rectangle(topLeft, bottomRight);
}
Rectangle[] prefixIntersection = new Rectangle[rectanglesCount + 1];
Rectangle[] suffixIntersection = new Rectangle[rectanglesCount + 1];
prefixIntersection[0] = suffixIntersection[0] = new Rectangle(
new Point(Integer.MIN_VALUE, Integer.MIN_VALUE),
new Point(Integer.MAX_VALUE, Integer.MAX_VALUE)
);
for (int i = 1; i <= rectanglesCount; i++) {
prefixIntersection[i] = rectangles[i - 1].intersect(prefixIntersection[i - 1]);
suffixIntersection[i] = rectangles[rectanglesCount - i].intersect(suffixIntersection[i - 1]);
}
for (int i = 0; i <= rectanglesCount; i++) {
if (prefixIntersection[i] != null) {
Rectangle intersection = prefixIntersection[i].intersect(suffixIntersection[rectanglesCount - i - 1]);
if (intersection != null) {
out.println(intersection.topLeft);
return;
}
}
}
throw new AssertionError();
}
```

**Bonus:** Solve the problem, if you need to find intersection of some *n* - *k* of *n* rectangles, if *k* ≤ 10. Without data structures.

Problem author: Errichto

Problem developers: zemen, Errichto, Kostroma, AlexDmitriev

**Code**

```
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
const int mod = 1e9 + 7;
signed main() {
#ifdef LOCAL
assert(freopen("test.in", "r", stdin));
#endif
int n;
cin >> n;
map<int, int> a{{INT_MIN, 1}, {INT_MAX, 0}};
set<int*> non0{&a.begin()->second};
for (int i = 0; i < n; ++i) {
string t;
int x;
cin >> t >> x;
if (t == "ADD") {
auto it = a.lower_bound(x);
assert(it != a.begin());
--it;
int ways = it->second;
auto m = a.emplace(x, ways).first;
non0.insert(&m->second);
} else {
auto m = a.find(x);
assert(m != a.end() && m != a.begin());
auto it = prev(m);
auto& w = it->second;
w = (w + m->second) % mod;
non0.insert(&it->second);
non0.erase(&m->second);
a.erase(m);
for (auto it2 = non0.begin(); it2 != non0.end(); ) {
if (*it2 == &it->second) {
++it2;
} else {
*(*it2) = 0;
it2 = non0.erase(it2);
}
}
}
}
int res = 0;
for (auto p : a) {
res = (res + p.second) % mod;
}
cout << res << '\n';
}
```

Problem author: zemen

Problem developers: yarrr, Kostroma

**Code**

```
void solve(__attribute__((unused)) bool read) {
int n;
cin >> n;
vector<int> b(n, 0);
for (int i = 0; i < n; ++i) {
cin >> b[i];
}
int mx = *max_element(all(b));
int start_pos = -1;
for (int i = 0; i < n; ++i) {
if (b[i] == mx && b[(i - 1 + n) % n] != mx) {
start_pos = i;
break;
}
}
if (start_pos == -1) {
if (mx == 0) {
cout << "YES\n";
for (int i = 0; i < n; ++i) {
cout << 1 << " \n"[i + 1 == n];
}
return;
}
cout << "NO\n";
return;
}
auto a = b;
for (int i = 1; i < n; ++i) {
int pos = (start_pos - i + n) % n, prev_pos = (start_pos + 1 - i + n) % n;
a[pos] += a[prev_pos];
if (i == 1) {
a[pos] += mx;
}
}
cout << "YES\n";
for (int x : a) {
cout << x << " ";
}
cout << "\n";
}
```

Problem author: Errichto

Problem developers: Kostroma, malcolm

**Code**

```
struct Point {
int x, y;
Point() {}
Point(int x, int y) : x(x), y(y) {}
void scan() {
cin >> x >> y;
}
auto key() const {
return make_pair(x, y);
}
bool operator < (const Point& ot) const {
return key() < ot.key();
}
bool operator == (const Point& ot) const {
return key() == ot.key();
}
Point operator + (const Point& ot) const {
return Point(x + ot.x, y + ot.y);
}
li sqr_dist() {
return x * 1LL * x + y * 1LL * y;
}
void normalize() {
auto g = gcd(x, y);
x /= g;
y /= g;
}
};
struct Hasher {
size_t operator () (const Point& pt) const {
return pt.x * 2352345 + pt.y;
}
};
enum Type {
INSERT = 1,
REMOVE = 2,
QUERY = 3
};
struct Query {
Type type;
Point pt;
int dist_id;
void scan() {
int type1;
cin >> type1;
type = Type(type1);
pt.scan();
}
};
void solve(__attribute__((unused)) bool read) {
int Q;
cin >> Q;
vector<Query> queries(Q);
map<li, vector<Point>> all_points;
vector<li> dists;
set<Point> have;
for (int i = 0; i < Q; ++i) {
queries[i].scan();
auto& pt = queries[i].pt;
if (queries[i].type != QUERY) {
all_points[pt.sqr_dist()].push_back(pt);
dists.push_back(pt.sqr_dist());
} else {
pt.normalize();
}
}
make_unique(dists);
for (auto& q : queries) {
q.dist_id = (int)(lower_bound(all(dists), q.pt.sqr_dist()) - dists.begin());
}
vector<vector<char>> has_point(dists.size());
vector<vector<Point>> points_by_dist_id(dists.size());
vector<vector<vector<Point>>> sum_points(dists.size());
unordered_map<Point, pair<int, int>, Hasher> point_position;
for (auto& item : all_points) {
make_unique(item.second);
int dist_id = (int)(lower_bound(all(dists), item.first) - dists.begin());
has_point[dist_id].assign(item.second.size(), false);
points_by_dist_id[dist_id] = item.second;
sum_points[dist_id].assign(item.second.size(), vector<Point>(item.second.size()));
for (int i = 0; i < item.second.size(); ++i) {
point_position[item.second[i]] = {dist_id, i};
for (int j = 0; j < item.second.size(); ++j) {
sum_points[dist_id][i][j] = item.second[i] + item.second[j];
sum_points[dist_id][i][j].normalize();
}
}
}
unordered_map<Point, int, Hasher> on_line;
unordered_map<Point, int, Hasher> good_pairs;
auto change_on_line = [&] (Point pt, bool add) {
pt.normalize();
if (add) {
++on_line[pt];
} else {
assert(on_line[pt] > 0);
--on_line[pt];
}
};
int n_points = 0;
for (auto& cur_q : queries) {
auto& pt = cur_q.pt;
int dist_id = cur_q.dist_id;
if (cur_q.type == INSERT) {
++n_points;
int pos = point_position[pt].second;
assert(!has_point[dist_id][pos]);
change_on_line(pt, true);
for (int i = 0; i < points_by_dist_id[dist_id].size(); ++i) {
if (i == pos || !has_point[dist_id][i]) {
continue;
}
++good_pairs[sum_points[dist_id][i][pos]];
}
has_point[dist_id][pos] = true;
} else if (cur_q.type == REMOVE) {
--n_points;
int pos = point_position[pt].second;
assert(has_point[dist_id][pos]);
change_on_line(pt, false);
for (int i = 0; i < points_by_dist_id[dist_id].size(); ++i) {
if (i == pos || !has_point[dist_id][i]) {
continue;
}
--good_pairs[sum_points[dist_id][i][pos]];
}
has_point[dist_id][pos] = false;
} else if (cur_q.type == QUERY) {
pt.normalize();
cout << n_points - 2 * good_pairs[pt] - on_line[pt] << "\n";
}
}
}
```

Problem author: zeliboba

Problem developers: Kostroma, AlexDmitriev

**Code**

```
private static final int MAX_WIDTH = 10000;
private static final int QUERIES = 5;
public static final long INF = 20000000000000000L;
long[][] memo = new long[QUERIES + 1][MAX_WIDTH + 1];
long dp(int guesses, long l) {
if (guesses == 0) {
return l;
}
if (l > MAX_WIDTH) {
return Math.min(INF, dp(guesses, MAX_WIDTH) + l - MAX_WIDTH);
}
if (memo[guesses][(int) l] != 0) {
return memo[guesses][(int) l];
}
long ans = l;
for (int i = 0; i < l; ++i) {
ans = dp(guesses - 1, ans);
++ans;
}
ans = dp(guesses - 1, ans);
return memo[guesses][(int) l] = Math.min(ans, INF);
}
private void run() throws IOException {
long l = 1;
long r = dp(QUERIES, 1);
for (int queriesNext = QUERIES - 1; queriesNext >= 0; --queriesNext) {
List<Long> query = new ArrayList<>();
long curL = l;
for (int i = 0, e = (int)Math.min(l, MAX_WIDTH); i < e; ++i) {
long end = dp(queriesNext, curL);
query.add(end);
curL = end + 1;
}
assert r == dp(queriesNext, curL);
out.print(query.size());
for (long x: query) {
out.print(" ");
out.print(x);
}
out.println();
out.flush();
System.out.flush();
int ans = readInt();
if (ans < 0) {
return;
}
if (ans > 0) {
l = query.get(ans - 1) + 1;
}
if (ans != query.size()) {
r = query.get(ans);
}
assert dp(queriesNext, l) == r;
}
}
```

Problem author: Kostroma

Problem developers: Kostroma, AlexDmitriev, gchebanov, malcolm

**Code**

```
const int C = 5032107 + 1;
int lp[C];
int fred[C];
int num_primes[C];
const int MAX_DIVISORS = 7;
const int MAX_ANS = 2 * MAX_DIVISORS;
int max_left[MAX_DIVISORS + 1][C];
int max_border[MAX_ANS + 1];
vector<int> cur_primes;
vector<int> divs;
void get_divisors(int n) {
divs = {1};
while (n > 1) {
int p = lp[n];
n /= p;
int sz = divs.size();
for (int i = 0; i < sz; ++i) {
divs.push_back(divs[i] * p);
}
}
}
void solve(bool read) {
vector<int> pr;
for (int i = 2; i < C; ++i) {
if (lp[i] == 0) {
lp[i] = i;
pr.push_back(i);
}
for (int j = 0; j < pr.size() && pr[j] <= lp[i] && i * pr[j] < C; ++j) {
lp[i * pr[j]] = pr[j];
}
}
fred[1] = 1;
for (int i = 2; i < C; ++i) {
int p = lp[i];
int cur = i / p;
if (cur % p == 0) {
fred[i] = fred[cur / p];
num_primes[i] = num_primes[cur / p];
} else {
fred[i] = p * fred[cur];
num_primes[i] = num_primes[cur] + 1;
}
}
for (int i = 0; i < C; ++i) {
for (int j = 0; j <= MAX_DIVISORS; ++j) {
max_left[j][i] = -1;
}
}
memset(max_border, -1, sizeof(max_border));
int n;
cin >> n;
int Q;
cin >> Q;
vector<int> a(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
a[i] = fred[a[i]];
}
vector<vector<pair<int, int>>> queries(n);
vector<int> res(Q);
for (int i = 0; i < Q; ++i) {
int l, r;
cin >> l >> r;
--l; --r;
queries[r].push_back({l, i});
}
for (int i = 0; i < n; ++i) {
get_divisors(a[i]);
for (int d : divs) {
int first_add = num_primes[a[i]] - num_primes[d];
for (int prev_ans = 0; prev_ans <= MAX_DIVISORS; ++prev_ans) {
int cur_left = max_left[prev_ans][d];
int cur_ans = first_add + prev_ans;
if (cur_ans <= MAX_ANS) {
relax_max(max_border[cur_ans], cur_left);
}
}
}
for (int d : divs) {
int first_add = num_primes[a[i]] - num_primes[d];
relax_max(max_left[first_add][d], i);
}
for (auto q : queries[i]) {
res[q.second] = MAX_ANS + 1;
for (int cur_ans = 0; cur_ans <= MAX_ANS; ++cur_ans) {
if (max_border[cur_ans] >= q.first) {
res[q.second] = cur_ans;
break;
}
}
assert(res[q.second] <= MAX_ANS);
}
}
int sum_ans = 0;
for (int i = 0; i < Q; ++i) {
cout << res[i] << '\n';
}
}
```

It is really funny that I used totally same constructive algorithm in B task, same amount of 9 and all other digits :)

How to solve C if we are asked to find any point which lies in maximum number of Rectangles?

Let's compress all values and sort points by

x-coordinate. Now we can see that there is two types of events: some rectangle "opens" and some rectangle "closes". So we can solve this problem with scanline onx-axis using any data structure that can add 1 on [l,r], subtract 1 on [l,r] and tell a position of maximum value in all structure (i.e. segment tree is good for this task).s.egorov how will you find the corresponding y-coordinates?

We have a segment tree built on

y-axis, therefore for eachywe know how many rectangles cover point (x_{current},y). I think it is not hard to determine anyin which maximum value is reached – just start at the root of segment tree and further at every step go to the son with bigger maximum value.I think scanline technique on x coordinate while maintaining a segment tree on y coordinate would be helpful in that case. Actually, I coded that solution during the contest, which wasted me like 30 minutes or so. XD

Find the intersecting segments in X and Y axis, then merge both results to get intersecting rectangle. It can be solved easily in

O(nlogn) using multisets: 42187139Some Intuition on solving Problem E:

Notice that

b_{1}=a_{1}moda_{2}, so we can writea_{1}=b_{1}+x_{1}a_{2}for some non-negative integerx_{1}.Similarly

a_{2}=b_{2}+x_{2a}_{3}. By substituting back continuously we havea_{1}=b_{1}+x_{1}b_{2}+ ... +x_{1}x_{2}...x_{n - 1}b_{n}+x_{1}x_{2}...x_{n}a_{1}.Hence

x_{1}x_{2}...x_{n}= 0 orb_{1}=b_{2}= ... =b_{n}= 0. Alsox_{i}can be zero (i.e.a_{i}=b_{i}) only ifb_{i - 1}<b_{i}. by the definition of modulo operation. Fix somea_{j}=b_{j}satisfying the above condition, then generate appropriatea_{j - 1}and so on such thata_{k}>b_{k - 1}for everyk.Very nice, thank you.

I don't know how to generate

a_{j - 1}.Could you tell me what do these mean？

The condition for appropriate

a_{k - 1}isa_{k - 1}>b_{k - 2}, i.e.b_{k - 1}+x_{k - 1}a_{k}>b_{k - 2}orx_{k - 1}a_{k}≥b_{k - 2}-b_{k - 1}+ 1. If RHS > 0 thenx_{k - 1}≥ceil((b_{k - 2}-b_{k - 1}+ 1) /a_{k}).Thank you very much!!!：）

Can anybody tell me what is wrong with my solution for problem C. I have used same concept as in editorial but am getting WA on testcase 14. Solution

UPD: NEVERMIND FOUND A TYPING MISTAKEyou'r algo is right.But the Problem is the way you print answer. See you'r last line in code.

this one cout << p << "\n" << suf[1] << endl;

My code is not expected to reach there cauz if it reached there then there is not such point possible, so I put that line for debugging purpose.

Also it is reaching the end in testcase 14.

The code given in the editorial for problem D seemed too complicated to me. So, I got the idea from the editorial and then read vntshh's solution which was very helpful to understand it. With the help of that, I wrote a commented solution for the problem. Here is the code, if you need any help: 42211321

Really?

You can replace the add(a, b) statements with (a + b) % mod, and it will still work. The functions are there just to avoid overuse of the % operation, as it is an expensive operation as compared to addition and subtraction. Further adding a lot of %s makes the code look messy.

Well, maybe modulo operation is just a little bit slower than addition and substraction, but, first of all, you do

`c = a + b`

when c is ll, but`a`

and`b`

are ints, so you have no profit of this thing. Also, in substraction, you even didn't changed the`c`

's type. As of mult, it's even worse. You still using the`%`

operator (so no boost in performance) and beside that, the multiplication itself is definitely wrong and would cause an overflow on big numbers(here it probably would not, because of the constraints, but if`p`

would be`p <= 10^10`

consider multiplication a pair of these). My point is, if you wanna do it — do it right, or don't at all.please explain solution of problem B

Considering the constraints of this problem, you just have to find 2 string(numbers) that alone would have max digit sums, but when added would have the minimum(1). So, a simple way to do this is just create 2 string (any way you want), when first string would be

`'9'*x + '0'*(x-1) + '1'`

and the second is just`'9'*x`

.`+`

is concatination,`c*x`

is repeating`x`

times char`c`

. Why? Because when added they would result in`'1' + '0'*(2*x-1)`

, so the digit sum is one. X can be 1000 for example.I didn't find any better alternatives for multiplications, so using mod. It won't overflow as multiplication is left to right associative, multiplication with 1ll converts it into a long long, and later the answer modulo 1e9+7, must be an int, so I return an int.

I use the sub operation when 0 <= a, b < mod. Note that a-b can not be <= -mod. So, even if it becomes negative, the absoute value of the result will never exceed mod-1, so adding mod converts the answer to a positive number. Furthermore, even if the answer is non-negative, it cannot exceed mod.

I accept that in c = a + b, c must have been an int. I wrote this function some time back, and not paying much attention to whether 2*(mod-1) (which is the max. value of a + b) will fit into an int or not, I took the result into a long long variable, but yes int will probably do in that case. So, Sorry for that.

`a`

and`b`

are ints. But, following today's "trends" you can see more problems involving modular arithmetics using the 64-bit ints, and then, your mult wont work. You can google for log n modular multiplication, if you are curious.Yeah, keep downvoting, show the codeforces' community actual face.

What is test 57 of problem E? My code is showing TLE on test 57 though its O(N). Here is the link to the code http://codeforces.com/contest/1028/submission/42212637

test: 2 1 2

when j equal n-1,

`while(i != j)`

work infinitelycan anyone give better explanation for problem B.

In problem B the idea is to maximize the s(a) and s(b) since m,n < 1150. In addition S(454545...45+5454....55)=1 which is the smallest possible number.

You can make another two strings to solve Problem B.

44444445+55555555=100000000

you can get shortest string a and b using this algorithm:

if(n<=5) a='5',b='5',n=0; so s(a)>=s(n) and s(b)>= s(n) and s(a+b)=1 well less or equal to any n. else { a='5',b='5',n-=5; while(n>=4) a='4'+a,b='5'+b,n-=4; }

because of when n-=4, s(a)+=4 and s(b)+=5, so it can ensure that s(n)<=s(a) and s(n)<=s(b).

I am getting heap buffer overflow in problem C while it runs fine on my computer. Can somebody check my code. 42215352

instead of cs* tmp = (cs*)malloc(sizeof(cs*)); you should write cs* tmp = (cs*)malloc(sizeof(cs));

It works. Thanks

In problem D, what is the reason for adding m + 1 instead of m in the answer for the undetermined directions of remaining orders?

If the values of the undetermined n ADD orders are v1, v2, ... vn (in ascending order), so in one possible assignment all of them can be sell orders, or the first one is buy and the rest are sells, or the first two are buys and the rest are sells, ...... or all of them are buys. These are n+1 possible assignments.

Alternative solution for problem C:

Let x1, x2, and y1, y2 be the maximum two left x-coordinates and bottom y-coordinates of the rectangles, respectively. Then the answer is one of those four combinations, i.e. (x1, y1), (x1, y2), (x2, y1), (x2, y2).

What's the reasoning behind it?

First, there's such a point (x, y) that satisfies the condition (possible answer) and its x value is the x-value of some rectangle, and likewise y-value. (*)

WLOG, assume that x1 <= x2 and y1 <= y2. (These are the same values as I assumed in the above comment). Then if x < x1 or y < y1, then this point would not be in at least two rectangles, that's why it must be the case that x >= x1 and y >= y1. Combining this with (*) proves the statement.

Would it?

SpoilerIn this case, actually all four combinations can be the answer.

The solution to the problem http://codeforces.com/contest/1028/problem/C is almost the same as that of this problem http://codeforces.com/contest/1029/problem/C cool to have two consecutive rounds with similar problems.

"Bonus: Solve the problem, if you need to find intersection of some n - k of n rectangles, if k ≤ 10."

I suppose it is very standard task to find a place where biggest number of rectangles intersect (no matter whether it is n-1, n-10 or 2137 for n=1e5). You simply sweep them from left to right with appropriate segment tree. It was given as a task on Polish OIG long ago which is contest for <=15 year old guys :P

Come on man, it's not interesting. Better find a solution in

O(nk^{2}).Seems, like the following works: Solve independent for X and Y. Every rectangle is just segment on axis X and the same for Y. Now we can easy find in

O(N×log(N)) allX-es, which covered by at leastn-krectangles(now segments), there will beO(K) suchx-es, after do the same foryand after that brute every such point inO(N). Is it ?Maybe it's not very interesting, but it seems like you guys missed it :D. Nevermind. Could you explain your solution? (I presume it is not solution mentioned here already 2 times since this one contains from sorting)

Lol, of course we didn't miss it)

Our approach is the following: the

x-coordinate of the result will be either one of thek+ 1 minimum rightx-borders or one of thek+ 1 maximum left borders. The same withy. So we have a solution inO(nk^{2}), which is very easy and fast to write :)can you explain for Case k = 2 ...

Hint: solve problem for segments first, not for rectangles. If all segments intersect, then the leftmost right border lies inside their intersection. So if you erase any two segments, others will intersect in one of the 3 leftmost right borders anyway, if they intersect at all, because in the worst scenario you erased these two segments which had two leftmost right borders.

I actually solved problem C with this approach, for k = 2.

can we solve G without dp?can we say that dp(l,q)=((l+1)^q-l)

In problem F, can you explain why number of points (x, y) with x^2 + y^2 = C is equal to the number of divisors of C after removing all the prime divisors of 4k+3 form?

I don't know if there's a natural bijection between divisors and positive solutions to

x^{2}+y^{2}=C; but I know that both numbers are equal to whereb_{i}are the exponents in the prime factorisation ofC(assuming all prime factors are of the form 4k+ 1; other primes won't increase the number of solutions) (the formula is off by one ifCis a square, because then there is a solution withy= 0 that is counted by ).Here's a sketch of how to derive the formula using Gaussian integers (they might seem scary, but I think the theory is also very beautiful):

First, note that

N(x+iy) =x^{2}+y^{2}is amultiplicativefunction ; that is,N(z_{1}·z_{2}) =N(z_{1})·N(z_{2}).Second, recall that has unique factorisation; that is, any can be uniquely expressed as a product of "Gaussian primes" and a unit (one of 1,

i, - 1, and -i). (There is the slightly annoying fact that each Gaussian prime has 4 associates including itself, but really they are the same. You can avoid this annoyance by picking your favourite among the associates and only using that one for factorisations, like how, in , you might write - 15 = ( - 1)·3·5 instead of - 15 = 1·( - 3)·5; we prefer 3 over - 3.) Now since the norm is multiplicative, and units have norm 1, you can determineN(z) from the multiset of Gaussian primes in the factorisation ofz. Since we want positive integer solutions,z=x+iyhas to lie in the first quadrant, so we will always have 1 choice of unit for any given multiset (ifCis a square, our formula also counts the solution withy= 0). So the number of solutions is the number of multisets of Gaussian primes such that the product of the norms isC.Finally, we need the classification of Gaussian primes: each Gaussian prime either has norm 2 (only one such Gaussian prime),

p= 4k+ 1 (twoGaussian primes for eachp), orq^{2}(q= 4k+ 3) (only one Gaussian prime for eachq). So the multisets are not too hard to count: If , with and , then the number of multisets is 0 if somec_{j}is odd, and otherwise. (The only choice is in how to choose the primes of normp_{i}= 4k+ 1: you need to distributeb_{i}among two Gaussian primes, so there areb_{i}+ 1 possibilities.)Also, I guess the limits on

x,ywere increased. The maximal number of solutions forC≤ 2·112904^{2}seems to be 196, which is achieved byC= 5^{2}·13·17·29·37·41·53 = 12882250225. However, only 172 of the solutions have both coordinates ≤ 112904. For the record, here's a program that generates the points with unnecessary efficiency.CodeWow, too much new knowledge. Thanks for your response!

For bonus task C :Sweep only on x first, now one can prove that there will be at most 2*k + 1 points(while sweeping), where there are n-k rectangles above it. For each of these x sweep on y to find if there is a y that actually contains n-k rectangles.

Complexity O(n*k*logn);

2*k + 1 points because -> suppose I reach a x where there are n-k rectangles above on the subsequent points the number of rectangles may increase decrease or remain saim. In worst case it can form the pattern n-k, n-k+1, .. n , n-1, n-2 .. n-k.

Solution : 42217561

For Problem C, You can use multiset to get O(n log n) with a simpler solution 42241507

1700 ms, using "n log n" solution. Let's see why.

No fast input.

Let's count log n operations actually. So we have 4 log n in input, so

`O(4*N log N)`

. + 12 log n operations in computing intersections(notice the`find()`

operations), so`O(12*N log N)`

. In result we have`O(16*N log N)`

. TYI,`log2(10^5) ~= 17`

.Summing up, your constant is almost as high as

`log N`

multiplier, which means, you have almost`O(N log^2 N)`

solution.I hope you understand that 300 ms is not that far from the TLE, so next time i suggest you to optimize your solutions.

Thank you for your details analysis !

I actually find that prefix and suffix array way(editorial) harder and ugly.(Maybe it's just me)

Well i added Fast IO to the same solution and got AC with 982 ms 42251111.

It's still far slower that this random submission of 180 ms i picked, 42249815.

But mine is much cleaner, you might agree.

Yeap, as for cleanness of code, definitely. As for time, of course, asymptotic is different, nothing surprising.

I wrote a very similar solution during the contest but with fast input and it passed in about 900 ms. But anyway it can be optimized by keeping track only of the maximum 2 and minimum 2 of bottom left x & y and top right x & y respectively. It will be O(N).

For bonus C:

X,Ycan't be answer if we findkrectangles such thatx2[i] <X, or if there existkrectangles such thatx1[i] >X. Similarly for Y. Let's sortx2,y2 in ascending order,x1,y1 in descending order. We get thatx1[k] ≤X≤x2[k],y1[k] ≤Y≤y2[k]. Then check all possible 4·k^{2}variants.Solution: 42165553.

Phew. Solved G by casework, complexity

O(4·10^{4}) and even that comes from just building the query lists, all decisions areO(1). It goes like this:If we're considering a range [

m,M] withm≥ 10^{4}, the solution is just 10^{4}+ 1-nary search, for which it's easy to calculate the maximum possible value ofM-m+ 1 given the number of remaining questions. Since we need to ask for at most one number until getting an answer > 0, the smallest possible value of the number in the first query is uniquely given: 204761410474.The optimal 2-question strategy without the 10

^{4}constraint is just to ask about 2m, 2(2m+ 1), 2(2(2m+ 1) + 1) etc., using as many numbers as we can, so that in the next question, we'd have at worstM= 2m- 1 and could ask about all numbers in the range [m, 2m- 1].Let's assume we got answer 0, since this is the only interesting case. The next question is for some number

x< 10^{4}. Now, depending on the answer,m= 7, can ask about 7 numbers and it's pretty clear that they need to be less than 10000, so the 2-question strategy says they should be 14, 30, 62, 126, 254, 510, 1022, withM≤ 2045 so this could workM= 2045 in that case, the number we need to ask about in this question (the 2nd question) needs to bex= 2046m= 2047 andM= 204761410473; there are 3 questions leftMis so large (much greater than 10^{8}), the largest number to ask about must beysuch that [y+ 1,M] can be handled using the "over 10000" strategy described at the topM-y≤ (10^{4})(10^{4}+ 1) + 10^{4}and optimallyy=M- 10^{4}(10^{4}+ 2)y- 1, so it'sM+ 1 - 2(10^{4}+ 1)^{2}, the next smaller number isM+ 1 - 3(10^{4}+ 1)^{2}etcNow there are 2 queries left, we have

M= 20468426 andm= 2047 and there isn't much of a choice. Since the last query needs to contain up to 10000 consecutive numbers, the largest number must be 20468426 - 10000, the second largest 20468426 - 1 - 2·10000 etc. This way, we can find 2045 numbers, the last of which is 16382. There are 2 numbers left and they can be decided based on the 2-query strategy with smallM: 2·2047 and 2(2·2047 + 1), which are 4094 and 8190.As it turns out, if the answer is 2 now, we have

m= 8191 andM= 16381, soM= 2m- 1, so this strategy proves that the bounds really are tight — the paths in the decision tree correspond to disjoint sets of answers.The above is an excellent example of how NOT to solve programming problems.

For problem A: if you find 'B' while searching from top, you don't need to do it from bottom. It's a square, so count B's in a row and get a size of it's side. As you already got the upper left corner, further calculations of the center is obvious.

In question d why we multiply ans with m+1 at the end?????

Its good if anyone try to explain this with an example.

I am not able to understand plz helppppp anyone.. Thankyou.

For problem C: Rectangles, is there a solution using convex hull technique? Can someone explain it to me.

In problem H, shouldn't it be relax best[k+dist] with dp[val][k] not dp[val][dist]?

I found a typo in the solution for Problem H,

`Before doing this for i, we need to update best array: for each val | ai and aival having dist primes in factorization and for each k≤7 relax best[k+dist] with dp[val][dist]. Then all queries with right border equal to i can be answered in O(Mans) time, where Mans≤14.`

We should relaxbest[k+dist] withdp[val][k] instead ofdp[val][dist].I have a solution for C with O(n) and also for bonus problem with O(k*n). My submission: my_submission Initial result is 1st rectangle. I do a for loop from 2 to n and find intersecting rectangle of the result and each rectangle from 2nd to n-th. If intersecting rectangle is empty, I will skip this rectangle and dont include it in the result, but I keep it in an archive. When size of the archive is 2, it means I skip 2 rectangles and will have wrong result. Then, if this happen, I make sure that these 2 rectangles must be a part of the final result, so I break the for loop, do a for loop again from 1 to n with initial result is intersecting rectangle of 2 rectangles in the archive. Final result is initial rectangle after for loop. For bonus problem, I also use this technique with condition to break the first loop is the size of archive exceed k instead of 1. Then with each rectangle in k+1 rectangles in the archive, I will do a for loop from 1 to n and try to find valid result and stop when I get an valid one.