Educational Round #2 — Editorial
Find the smallest and the largest elements in the array. Then, compute the sum of the weights of all students, excluding those with the smallest or largest values. Let this sum be and the number of such students be .
Finally, compute the average weight of the students by dividing by and print the result, rounded to the nearest whole kilogram.
Declare the array.
int w[1000];
Read the input data. The count of input numbers is stored in the variable .
n = 0; while (scanf("%d", &w[n]) == 1) n++;
Find the smallest element and the largest element in the array.
min = max = w[0]; for (i = 0; i < n; i++) { if (w[i] > max) max = w[i]; if (w[i] < min) min = w[i]; }
Compute the sum of weights and the number of students , excluding those with the highest and lowest weights.
s = cnt = 0; for (i = 0; i < n; i++) if (w[i] != min && w[i] != max) { s = s + w[i]; cnt++; }
Print the result, rounded to the nearest whole kilogram.
printf("%.0lf\n", 1.0 * s / cnt);
Algorithm implementation — min_element, max_element
Declare the array.
vector<int> w;
Read the input data.
while (scanf("%d", &x) == 1) w.push_back(x);
Find the smallest element and the largest element in the array.
min_el = *min_element(w.begin(), w.end()); max_el = *max_element(w.begin(), w.end());
Compute the sum of the weights and the number of students , excluding those with the highest and lowest weights.
s = cnt = 0; for (int x : w) if (x != min_el && x != max_el) { s += x; cnt++; }
Print the result, rounded to the nearest whole kilogram.
printf("%.0lf\n", 1.0 * s / cnt);
One of the farming chores Farmer John dislikes the most is hauling around lots of cow manure. In order to streamline this process, he comes up with a brilliant invention: the manure teleporter! Instead of hauling manure between two points in a cart behind his tractor, he can use the manure teleporter to instantly transport manure from one location to another.
Farmer John's farm is built along a single long straight road, so any location on his farm can be described simply using its position along this road (effectively a point on the number line). A teleporter is described by two numbers and , where manure brought to location can be instantly transported to location , or vice versa.
Farmer John wants to transport manure from location to location , and he has built a teleporter that might be helpful during this process (of course, he doesn't need to use the teleporter if it doesn't help). Please help him determine the minimum amount of total distance he needs to haul the manure using his tractor.
Input. One line contains four integers: and describing the start and end locations, followed by and describing the teleporter. All positions are integers in the range , and they are not necessarily distinct from each-other.
Output. Print a single integer giving the minimum distance Farmer John needs to haul manure in his tractor.
Examples. In this example, the best strategy is to haul the manure from position to position , teleport it to position , then haul it to position . The total distance requiring the tractor is therefore .

beginrow
3 10 8 2
3
Farmer John has the following manure movement options:
Drive directly from to , covering the distance ;
Drive a tractor from to , teleport from to , and then drive the tractor again from to . The total distance covered by the tractor is ;
Drive a tractor from to , teleport from to , and then drive the tractor again from to . The total distance covered by the tractor is ;
The smallest of these three values will be the answer.
Example
In the given example, the best strategy is to haul the manure from position to position , teleport it to position , and then haul it to position . The total distance covered by the tractor is therefore .
Read the input data.
scanf("%d %d %d %d", &a, &b, &x, &y);
Find the answer — the minimum of the three values.
res = abs(a - b); res = min(res, abs(a - x) + abs(b - y)); res = min(res, abs(a - y) + abs(b - x));
Print the answer.
printf("%d\n", res);
Find a number between and (inclusive) that has the maximum number of prime factors in its factorization. If there are multiple such numbers, print the largest one.
For example, for the answer is , as it is the largest number whose prime factorization includes two factors: and .
Input. One integer .
Output. Print the desired number.
beginrow
7
6
To ensure that a number not exceeding has the maximum number of divisors, it should be represented as the product of the smallest possible prime numbers.
For example, consider numbers of the form . Find the largest such that . The number of divisors of is given by .
Next, examine the number . The number of its divisors is , which is greater than .
Thus:
If , the desired number is ;
Otherwise, the answer is .
Finally, consider the special case when . For this value, the answer is .
Example
Let . The largest power of not exceeding is . The number has divisors.
Now, consider the number . The number of its divisors is:
Since does not exceed , it will be the desired number for .
Read the input value of .
scanf("%d",&n);
Find the largest such that .
p = 1; while (p * 2 <= n) p = p * 2;
Next, compute .
p1 = p / 2 * 3;
Determine the result . If , the result will be .
if (p1 <= n) res = p1; else res = p; if (n == 1) res = 1;
Print the answer.
printf("%d\n",res);
Find the value of the function
Input. Two integers .
Output. Print the value of the function .
2 3
4
34 12
6
Implement a recursive function with memoization.
Declare a two-dimensional array to store the function values: .
long long dp[51][51];
Implement the recursive function f with memoization.
long long f(int x, int y) { if (x <= 0 || y <= 0) return 0; if (dp[x][y] != -1) return dp[x][y]; if (x <= y) return dp[x][y] = f(x - 1, y - 2) + f(x - 2, y - 1) + 2; return dp[x][y] = f(x - 2, y - 2) + 1; }
The main part of the program. Read the input data.
scanf("%d %d",&x,&y);
Initialize the cells of the array with the value .
memset(dp,-1,sizeof(dp));
Call the function and print its value.
printf("%lld\n",f(x,y));
One day people ( is even) met on a plaza and made two round dances. Find the number of ways people can make two round dances if each round dance consists of exactly people. Each person should belong to exactly one of these two round dances.
Round dance is a dance circle consisting of or more people. Two round dances are indistinguishable (equal) if one can be transformed to another by choosing the first participant. For example, round dances and are indistinguishable.
Input. One even integer .
Output. Print the number of ways to make two round dances. It is guaranteed that the answer fits in the -bit integer data type.
Examples. For example, for the number of ways is :
one round dance — , another — ;
one round dance — , another — ;
one round dance — , another — .
4
3
First, we should select people for the first circle dance. This can be done in ways. Let's count the number of ways to arrange people within one circle dance. Fix the person who will be first, after which the remaining people can be arranged in any order, namely ways. The number of ways to form two circle dances is:
The division by is necessary so that we do not distinguish between pairs of circle dances and . For example, for , the divisions into circle dances and are considered the same.
Simplifying the given formula, we get the answer:
Example
For example, for the number of ways is :
One round dance — , another — ;
One round dance — , another — ;
One round dance — , another — .
According to the formula for , the answer is
Let's construct all distinguishable circle dances for . We place participant in the first position. In the remaining three positions, any permutation of the other three participants can be placed.
By rotating any of these arrangements in a circle, we can obtain indistinguishable circle dances. For example, the following arrangements are indistinguishable (consider the cyclic shifts of the last permutation):
There are circle dances with participants. However, the number of distinguishable circle dances for is .
The fact function computes the factorial of the number .
long long fact(int n) { long long res = 1; for (int i = 2; i <= n; i++) res *= i; return res; }
The main part of the program. Read the input value of .
scanf("%d", &n);
Compute and print the result.
res = 2 * fact(n - 1) / n; printf("%lld\n", res);
You are given a matrix of size with special cells. You need to reach cell starting from . From any cell, you are allowed to move only to the right or down.
Each of the special cells has a certain power. The -th special cell has power , and if you pass through this cell, you gain this power.
Your task is to find the total power that can be collected over all possible paths from to .
Note that:
The power of a path is the sum of the values of all special cells visited along this path.
Regular cells that are not special have power equal to zero.
Input. The first line contains an integer — the number of test cases.
The first line of each test case contains three integers and , where is the size of the grid, and is the number of special cells.
Each of the next lines contains three integers and , where is the position of a special cell, and is its power.
Output. For each test case, print on a separate line the total power that can be collected. Since the result may be very large, output it modulo .
1 2 2 2 1 2 4 2 1 7
11
Let denote the number of paths on a grid from cell to cell . Then
The number of paths from cell to cell that pass through a special cell is equal to . Multiplying this number by gives the total power of all paths passing through cell .
It remains to sum the powers of all paths passing through the special cells. The answer will be equal to the sum:
Example
In the given example, special cells are specified.
Exactly one path passes through the cell with power .
Exactly one path passes through the cell with power .
Thus, the total power is .
Declare the arrays:
contains the factorials of numbers modulo ,
contains the inverse values of these factorials modulo :
#define MAX 800001 ll fact[MAX], factinv[MAX];
The pow function computes the power of a number modulo : .
ll pow(ll x, ll n, ll p) { if (n == 0) return 1; if (n % 2 == 0) return pow((x * x) % p, n / 2, p); return (x * pow(x, n - 1, p)) % p; }
The inverse function finds the number that is the modular inverse of with respect to a prime modulo . Since is a prime number, by Fermat's Little Theorem the following holds:
This can be rewritten as , from which it follows that the modular inverse of is .
ll inverse(ll x, ll p) { return pow(x, p - 2, p); }
The Cnk function computes the binomial coefficient using the formula:
ll Cnk(int n, int k) { return ((fact[n] * factinv[k]) % MOD * factinv[n - k]) % MOD; }
The ways function calculates the number of paths on an grid from cell to cell . Since any path between these points has length and contains exactly horizontal steps, the number of paths is equal to .
ll ways(int n, int m) { return Cnk(n + m, m); }
The main part of the program. Fill the arrays of factorials and inverse factorials .
fact[0] = 1; for (i = 1; i < MAX; i++) fact[i] = (fact[i - 1] * i) % MOD; factinv[0] = 1; for (i = 1; i < MAX; i++) factinv[i] = inverse(fact[i], MOD);
Process the tests sequentially.
scanf("%d", &tests); while (tests--) {
Read the data for the current test.
scanf("%d %d %d", &n, &m, &k);
Store the total obtained power in the variable .
res = 0;
Process the special cells.
for (i = 0; i < k; i++) { scanf("%d %d %d", &x, &y, &p); res = (res + (ways(x - 1, y - 1) * ways(n - x, m - y)) % MOD * p) % MOD; }
Print the answer for the current test.
printf("%lld\n", res); }
In the land of Smeshariki, a new season has begun! Now all the heroes are setting out on a journey. To do this, they need to gather at a single point, and from there continue their quest to conquer the world. Losyash, who coordinates the actions of the Smeshariki, knows the coordinates of all the participants. Help him determine the minimum number of seconds required for all the Smeshariki to gather together.
Initially, each Smesharik is located at a node of the integer grid. If a Smesharik is at point , then in one second they can move to one of the points , , , , or remain at .
Input. The first line contains a single integer — the number of Smeshariki. The next lines specify their initial positions. Each position is given by two integers and .
Output. Print the minimum number of seconds required for all the Smeshariki to gather at a single point.
1 1 1
0
2 1 3 4 4
2
3 0 0 3 3 0 3
3
Let a Smesharik be at the point . Then in seconds, it can reach any integer point inside the diamond, as shown in the figure.
It is required to find the smallest positive integer such that the diamonds of the corresponding size for each Smesharik will all have at least one common integer point. Let us consider the third test and illustrate the diamonds for the three Smeshariks at .
For , the Smeshariks can, for example, meet at the point or .
Let us rotate the coordinate system by relative to the origin. Under this transformation, the diamonds will turn into squares. Let us write down the rotation formulas:
Or, in Cartesian coordinates:
Let us eliminate the irrationality by stretching the image by a factor of . To do this, we use the following transformation:
Now let us transform our three points:
Let us find the coordinates of the rectangle containing all the points — the transformed initial coordinates of the Smeshariks. Denote:
;
;
Then the rectangle with opposite corners and contains all the points . Moreover, it is the minimum area rectangle whose sides are parallel to the coordinate axes.
In our example, such a rectangle is .
The meeting point of the Smeshariks will be the center of this rectangle, that is, the point with coordinates
Now we need to find the minimum time in which all the Smeshariks can reach the point from their positions . For the rotated diamond (a square in the new coordinate system), the distance from the point to is calculated using the formula:
Thus, all the Smeshariks will be able to gather at the point in a time equal to the maximum of these distances:
Let us define the constant infinity .
typedef long long ll; #define INFL (ll)4e18
Store the input points in the array .
vector<pair<ll, ll>> inp;
The function calc computes the distance from the point to the farthest Smesharik. The transformed coordinates of the Smeshariks are stored in the array .
ll calc(ll x, ll y) { ll res = 0; for (auto p : inp) res = max(res, max(abs(p.first - x), abs(p.second - y))); return res; }
The main part of the program. Read the input data.
cin >> n; minx = INFL; maxx = -INFL; miny = INFL; maxy = -INFL; for (i = 0; i < n; i++) {
Read the initial coordinates of the Smesharik . Perform a rotation of the coordinate plane and store the resulting coordinates in the array .
cin >> x >> y; nx = x + y; ny = -x + y; inp.push_back({ nx, ny });
After that, find the coordinates of the rectangle with opposite corners and , which contains all the points — the transformed coordinates of the Smeshariks.
minx = min(minx, nx); maxx = max(maxx, nx); miny = min(miny, ny); maxy = max(maxy, ny); }
Determine the meeting point of the Smeshariks — the center of the rectangle.
resx = (minx + maxx) / 2; resy = (miny + maxy) / 2;
Compute and print the minimum time required for all the Smeshariks to reach the point from their positions .
ans = calc(resx, resy); cout << ans << "\n";
Nurlashko, Nurbakyt, and Zhora are the last warriors of an ancient ninja clan fighting against the tyranny of Emperor Ren. After a crushing defeat in open battle, they decided to split their army into three camps and switch to guerrilla warfare.
However, the absurd reforms of Emperor Ren imposed strict rules: the roads between cities can only be traveled in one direction. Moreover, the directions were chosen in such a way that it is impossible, after traversing several roads, to return to the original city.
Now the clan is deciding where to place their camps. The emperor's army regularly conducts raids, checking various routes. If, during one such raid, the enemy manages to capture all three camps, the clan will be unable to regroup and will lose the war. Your task is to help choose three cities so that there is no path passing through all of them.
Input. The first line contains two integers — the number of cities and roads in the empire.
The following lines each contain two integers , describing a directed road from city to city .
Output. Print three integers — the indices of the cities where the clan should place their camps. If no such triple of cities exists, print . If there are multiple solutions, you may output any of them.

3 2 1 2 2 3
-1
3 2 1 2 1 3
2 3 1
The task is to find any three vertices in the graph that are not located on a single path.
To do this, we run Kahn’s topological sorting algorithm. We look for two vertices that appear in the queue at the same time. In this situation, there is no path that passes through both of these vertices. By adding any third vertex to them, we obtain the desired solution.
If, during the execution of Kahn’s algorithm, the queue never contains more than one vertex at a time, this means that all vertices in the graph lie on a single path.
Example
The graphs from the sample tests have the following structure:
In the first example, all three vertices lie on a single path.
In the second example, there exist three vertices that do not lie on a single path.
Declare the data structures. The input graph is represented by the adjacency list , and the in-degrees of the vertices are stored in the array .
vector<vector<int> > g; vector<int> InDegree; deque<int> q;
Read the input data.
scanf("%d %d", &n, &m); g.resize(n + 1); InDegree.resize(n + 1); for (i = 0; i < m; i++) { scanf("%d %d", &a, &b); g[a].push_back(b);
For each edge , increment by .
InDegree[b]++; }
All vertices with an in-degree of zero are added to the queue .
for (i = 1; i < InDegree.size(); i++) if (InDegree[i] == 0) q.push_back(i);
The three desired vertices are stored in the variables and .
x = y = -1;
Continue executing the algorithm as long as the queue is not empty.
while (!q.empty()) {
If the queue contains more than one vertex at the same time, this means that the solution has been found.
if (q.size() > 1) { x = q[0]; y = q[1]; break; }
Extract the vertex from the queue — it will become the current vertex in the topological order.
v = q.front(); q.pop_front();
Remove from the graph all edges of the form . For each such edge, decrease the in-degree of the vertex . If the in-degree of becomes zero, add it to the queue.
for (int to : g[v]) { InDegree[to]--; if (InDegree[to] == 0) q.push_back(to); } }
Kahn's algorithm is complete. If the value of is still , this means that no solution exists.
if (x == -1) printf("-1\n"); else {
If a solution exists, choose as the smallest vertex different from and .
z = 1; while (z == x || z == y) z++; printf("%d %d %d\n", x, y, z); }
Fernando was hired by the University of Waterloo to finish a development project the university started some time ago. Outside the campus, the university wanted to build its representative bungalow street for important foreign visitors and collaborators.
Currently, the street is built only partially, it begins at the lake shore and continues into the forests, where it currently ends. Fernando’s task is to complete the street at its forest end by building more bungalows there. All existing bungalows stand on one side of the street and the new ones should be built on the same side. The bungalows are of various types and painted in various colors.
The whole disposition of the street looks a bit chaotic to Fernando. He is afraid that it will look even more chaotic when he adds new bungalows of his own design. To counterbalance the chaos of all bungalow shapes, he wants to add some order to the arrangement by choosing suitable colors for the new bungalows. When the project is finished, the whole sequence of bungalow colors will be symmetric, that is, the sequence of colors is the same when observed from either end of the street.
Among other questions, Fernando wonders what is the minimum number of new bungalows he needs to build and paint appropriately to complete the project while respecting his self-imposed bungalow color constraint.
Input. The first line contains one integer , the number of existing bungalows in the street. The next line describes the sequence of colors of the existing bungalows, from the beginning of the street at the lake. The line contains one string composed of lowercase letters ("" through ""), where different letters represent different colors.
Output. Print the minimum number of bungalows which must be added to the forest end of the street and painted appropriately to satisfy Fernando's color symmetry demand.
3 abb
1
12 recakjenecep
11
15 murderforajarof recakjenecep
6
A minimal number of characters must be added to the given string to turn it into a palindrome.
To do this, we need to find the longest palindromic suffix of the string, then take the prefix before the start of that palindrome, reverse it, and append it to the original string.
For example, the longest palindromic suffix of the string abcxqx is . The prefix before it is . We reverse it (getting ) and append it to the original string.
Consider the string . Compute the -function for this string.
Next, find the smallest index (such that ) for which the equality holds. Among such indices, the value will be maximal. The minimum number of characters that need to be appended to the original string to form a palindrome is .
For the string "" (length ), the required index is , since .
Example
Let’s consider the first example. Compute the -function for the string .
The smallest index for which the equality holds is . Indeed: . Therefore, the answer is . That is, it is enough to add a single character '' to the string "" to obtain the palindrome "".
The function z constructs and returns the -function for the string .
vector<int> zfun(string s) { int i, l, r, len = s.size(); vector<int> z(len, 0); l = r = 0; for (i = 1; i < len; i++) { if (i <= r) z[i] = min(r - i + 1, z[i - l]); while (i + z[i] < len && s[z[i]] == s[i + z[i]]) z[i]++; if (i + z[i] - 1 > r) { l = i; r = i + z[i] - 1; } } return z; }
The main part of the program. Read the input string .
cin >> n; cin >> s;
Construct the string .
rs = s; reverse(rs.begin(), rs.end()); rs += s;
Compute the -function for the string .
z = zfun(rs);
Find the smallest index for which the equality holds. Among all such indices, the value of will be the largest.
for (i = n; i < rs.size(); i++) if (i + z[i] == 2 * n) {
Print the answer.
cout << n - z[i] << endl; break; }
Along the Almaty - Taraz highway, there are n villages, numbered from 1 to n. With the arrival of winter, m unknown traders brought knitted hats from a certain aul and began selling them in these villages. The traders follow two principles:
They do not sell in the same place for more than one day.
Each day, they increase the price of a hat.
More formally, each -th trader:
Starts selling in village with an initial price of per hat.
Moves to a neighboring village each day: if they sold in village yesterday, they sell in village today.
Increases the price by each day: if the price was yesterday, today it is .
Finishes selling in village (including selling in on the last day).
For each village, determine the maximum price of a single hat throughout the entire trading history.
Input. The first line contains two integers and — the number of villages and the number of traders, respectively.
The next lines each contain three integers: and — the starting and ending villages, as well as the initial price of a hat for the -th trader.
Output. Print integers, where the -th number represents the maximum price of a hat throughout the entire trading history in the -th village. If no trade took place in a particular village, print .
5 2 1 3 2 2 4 6
2 6 7 8 0
6 4 4 4 3 1 2 5 5 6 1 6 6 1
5 6 0 3 1 2
Construct a segment tree over the range and initially set all values to zero. Suppose a trader sold hats in villages , starting with a price of . Divide the segment into fundamental segments . Then, for the node corresponding to the segment , store the value
For example, let , and the first trade covers the cities numbered from to , starting with a price of . Then, the segment will be split into fundamental segments: . After processing the first operation, the segment tree will look as follows:
If the fundamental segment contains the value , it means that:
The trader sold hats in all cities from to .
In city , the hat was sold for the price , in city for the price , and so on, up to city , where the price was .
Consider the procedure for processing the query (the segment where the trader is trading) over the range , if the initial price of the hat is .
In the left subsegment, the merchant will sell hats in cities, starting at the price . In the right subsegment, the first price of the hat in the city where the merchant arrives will be . Thus, in the segment with indices , the trade will start at the price . However, if (which is possible if the entire query segment lies within the right subsegment), set .
Consider the segment , which has two subsegments: and . If the trader sold a hat for price in city , then in city , the price will be .
During the query processing, implement value propagation that maintains the maximum.
To print the answer, traverse the tree, propagate all values to the leaves, and then print them.
Example
Consider the execution of the two queries given in the example. Split the query segments into fundamental segments:
;
.
Declare an array to store the segment tree.
#define MAX 300010 long long SegTree[4*MAX];
The Push function propagates the value from node to its children.
void Push(int v, int lpos, int mid, int rpos) { if (SegTree[v]) { SegTree[2 * v] = max(SegTree[2 * v], SegTree[v]); SegTree[2 * v + 1] = max(SegTree[2 * v + 1], SegTree[v] + mid - lpos + 1); SegTree[v] = 0; } }
The Update function performs the sale of hats over the segment , starting with the price .
void Update(int v, int lpos, int rpos, int left, int right, long long x) { if (left > right) return; if ((lpos == left) && (rpos == right)) SegTree[v] = max(SegTree[v], x); else { int mid = (lpos + rpos) / 2; Push(v, lpos, mid, rpos); int len = min(mid, right) - left + 1; if (len < 0) len = 0; Update(2 * v, lpos, mid, left, min(mid, right), x); Update(2 * v + 1, mid + 1, rpos, max(left, mid + 1), right, x + len); } }
The PrintResult function propagates the values from internal nodes to the leaves and prints the final state of the array.
void PrintResult(int v, int lpos, int rpos) { if (lpos == rpos) printf("%lld ", SegTree[v]); else { int mid = (lpos + rpos) / 2; Push(v, lpos, mid, rpos); PrintResult(2 * v, lpos, mid); PrintResult(2 * v + 1, mid + 1, rpos); } }
The main part of the program. Read the input data.
scanf("%d %d", &n, &m); memset(SegTree,0,sizeof(SegTree));
Process queries.
for(i = 0; i < m; i++) { scanf("%d %d %lld", &l, &r, &x); Update(1,1,n,l,r,x); }
Print the result.
PrintResult(1,1,n); printf("\n");