Basecamp
    Home
    Problems
    Contests
    Courses
    Rating
    Posts
    Store
    Discord
Educational Round #3 — Editorial
Sign in
Tutorial•1 day ago

Educational Round #3 — Editorial

Eolymp #7832. Number of maximums

An array of n integers is given. Find the number of maximum elements in the array.

Input. The first line contains the number n (n≤100) — the number of elements in the array. The second line contains n integers, each with an absolute value not exceeding 100.

Output. Print the number of maximum elements in the array.

beginrow

Sample input
5
1 6 2 6 2
Sample output
2
Open problem
Solution

Find the maximum element of the array. Then, perform a second pass through the array to count the number of maximum elements.

Algorithm implementation

Declare an array.

int m[101];

Read the input array. Find its maximum element max.

scanf("%d", &n);
max = -2000000000;
for (i = 0; i < n; i++)
{
  scanf("%d", &m[i]);
  if (m[i] > max) max = m[i];
}
C++
7 lines
123 bytes

In the variable cnt, count the number of maximum elements.

cnt = 0;
for (i = 0; i < n; i++)
  if (m[i] == max) cnt++;

Print the answer.

printf("%d\n", cnt);
Eolymp #8352. Taxi

At rush hour, three taxi buses arrived at the stop simultaneously, all following the same route, and passengers immediately boarded them. The drivers noticed that the number of people in the different buses varied and decided to transfer some passengers so that each bus would have the same number of passengers. Determine the minimum number of passengers that need to be transferred for this.

Input. Three integers, not exceeding 100 — the number of passengers in the first, second, and third busses, respectively.

Output. Print a single number — the minimum number of passengers that need to be transferred. If this is impossible, print IMPOSSIBLE.

beginrow

Sample input
1 2 3
Sample output
1
Open problem
Solution

Let a,b,c represent the number of passengers in the first, second and third minibuses respectively. For the number of passengers in minibuses to be the equal after the transfer, the sum a+b+c must be divisible by 3.

Let d=(a+b+c)/3 be the number of passengers that should be in each minibus after the transfer. Then it is necessary to transfer from each minibus a certain number of passengers so that exactly d passengers remain in each. This tranfer is only possible if a minibus initially contains more than d passengers. For example, if a>d, then a−d passengers should be transferred from the first minibus. Similarly, b−d passengers should be transferred from the second minibus (if b>d), and c−d passengers from the third minibus (if c>d).

Algorithm implementation

Read the input data.

scanf("%d %d %d",&a,&b,&c);

If the total number of people is not divisible by 3, then print IMPOSSIBLE.

if((a + b + c) % 3 != 0)
  puts("IMPOSSIBLE");
else
{
  res = 0;

Compute the number d of people in minibuses after the transfer.

  d = (a + b + c) / 3;

In the variable res count the number of transfered people.

  if (a > d) res += a - d;
  if (b > d) res += b - d;
  if (c > d) res += c - d;

Print the answer.

  printf("%d\n",res);
}
Eolymp #7335. Saucepans and lids

A huge disaster occurred this morning at the café where you used to have snacks during your university studies. The cleaner, Larisa Ivanovna, accidentally knocked over one of the cabinets while sweeping the floor, causing all the kitchen utensils stored inside to scatter across the floor. Fortunately, it only contained saucepans with lids. However, some of them got bent or broken, so they had to be thrown away.

Now the schoolmaster wants to calculate the losses and determine how many new saucepans and lids should be purchased. But first, it is necessary to find out how many remaining saucepans can be covered by the remaining lids.

The saucepans and lids are round. A lid can cover a saucepans only if its radius is not less than the radius of the pot.

Input. The first line contains integers n,m (1≤n,m≤1000) — the number of remaining saucepans and lids. The second line contains n integers ai​ (1≤ai​≤1000) — the radii of the remaining saucepans. The third line contains m integers bi​ (1≤bi​≤1000) — the radii of the remaining lids.

Output. Print one number — the largest number of saucepans that can be covered by the available lids.

beginrow

Sample input
5 5
4 8 1 2 5
7 2 4 6 5
Sample output
4
Open problem
Solution

Sort the radii of the lids and the radii of the saucepans in ascending order. For the smallest saucepan, find the smallest lid that can cover it. Then, for the second smallest pan, find the smallest lid that fits it, and so on. The answer will be the number of saucepans that can be covered with lids.

Example

Let’s find the maximum number of pans for which lids can be matched in the given example.

Algorithm implementation

Declare arrays to store the radii of saucepans and lids.

#define MAX 1010
int pan[MAX], lid[MAX];

Read the input data.

scanf("%d %d",&n,&m);
for(i = 0; i < n; i++)
  scanf("%d",&pan[i]);
for(i = 0; i < m; i++)
  scanf("%d",&lid[i]);

Sort the radii of pans and lids.

sort(pan,pan+n);
sort(lid,lid+m);

Using the greedy method, search for the smallest lid each time that can cover the smallest pan.

for (i = j = 0; (i < n) && (j < m); j++)
  if (pan[i] <= lid[j]) i++;

Print the number of covered pans.

printf("%d\n",i);
Eolymp #1661. Aladdin's knapsack

Upon entering the treasure cave, Aladdin chose not to take the old, blackened lamp. Instead, he began filling his backpack with gold coins and precious gems. Of course, he wanted to take everything, but miracles don't happen — his backpack had a limited carrying capacity and might not withstand excessive weight.

Many times, he removed some items and replaced them with others, striving to maximize the total value of his backpack's contents.

The task is to determine the maximum value of the cargo that Aladdin can carry.

We assume that the cave contains n different types of items, with an unlimited number of each type available. The backpack can hold a maximum weight of s. Each item of type i has a weight of wi​ and a value of vi​ (i=1,2,...,n).

Input. The first line contains two positive integers s and n (1≤s≤250,1≤n≤35) — the maximum weight the backpack can carry and the number of item types.

The next n lines each contain two numbers wi​ and vi​ (1≤wi​≤250,1≤vi​≤250) — the weight and value of an item of type i.

Output. Print the maximum total value of the cargo that can be carried without exceeding the weight limit s.

beginrow

Sample input
10 2
5 10
6 19
Sample output
20
Open problem
Solution

Let dpk​[s] be the maximum value of cargo with a weight of at most s, considering only the first k types of items.

Now, consider two possible options when forming cargo of weight i:

  • Do not use an item of type k: In this case, the optimal value remains unchanged, meaning:

dpk​[i]=dpk−1​[i]
  • Use an item of type k: Then its weight wk​ will occupy part of the knapsack's capacity, and the value will increase by vk​, meaning:

dpk​[i]=dpk​[i−wk​]+vk​.

Since the goal is to maximize the cargo value, we obtain the following recurrence relation:

dpk​[i]=max(dpk−1​[i],dpk​[i−wk​]+vk​),wk​≤i≤s

Base cases:

dp0​[i]=0 и dpk​[0]=0

Let the function f(k,s) compute the maximum value of cargo that can be packed into a knapsack with a weight limit of s, using the first k types of items. Then, the next recurrence relation holds:

f(k,s)=max(f(k−1,s),f(k,s−w[k])+v[k])

Finally, we need to compute the value of f(k,s) using memoization.

Algorithm implementation

Declare the arrays:

  • w[i] — the weight of an item of type i;

  • p[i] — the value of an item of type i;

  • dp[i] — the maximum value of cargo with a weight of at most i;

#define MAXW 252
#define MAXN 37
int w[MAXN], p[MAXN];
int dp[MAXW];

Read the input data.

scanf("%d %d", &s, &n);
for (i = 0; i < n; i++)
  scanf("%d %d", &w[i], &p[i]);

Process n types of items sequentially.

for (k = 0; k < n; k++)
{

Update the values in the dp array, considering the possibility of using items of type k. Since the number of items of each type is unlimited, each item can be chosen multiple times.

  for (i = w[k]; i <= s; i++)
    dp[i] = max(dp[i], dp[i - w[k]] + p[k]);
}

Print the answer.

printf("%d\n", dp[s]);

Algorithm implementation — recursion

Declare the arrays:

  • w[i] — the weight of an item of type i;

  • p[i] — the value of an item of type i;

  • dp[i] — the maximum value of cargo with a weight of at most i;

#define MAXW 252
#define MAXN 37
#define INF 2000000000
int w[MAXN], v[MAXN];
int dp[MAXN][MAXW];

The function f(k,s) computes the maximum value of cargo that can be packed into a knapsack with a weight limit of s, using the first k types of items.

int f(int k, int s)
{

If k=0 or s=0, the knapsack is empty, and its value is 0.

  if (k == 0 || s == 0) return 0;

If s<0, we have exceeded the allowed weight, making this option invalid. Therefore, we return −INF (where INF is a sufficiently large number).

  if (s < 0) return -INF;

If the value of f(k,s) is already computed, return it.

  if (dp[k][s] != -1) return dp[k][s];

Compute f(k,s) and store it in dp[k][s].

  return dp[k][s] = max(f(k - 1, s), f(k, s - w[k]) + v[k]);
}

The main part of the program. Read the input data.

scanf("%d %d", &s, &n);
for (i = 1; i <= n; i++)
  scanf("%d %d", &w[i], &v[i]);

Compute and print the answer.

memset(dp, -1, sizeof(dp));
printf("%d\n", f(n, s));
Eolymp #11269. Lemurian parties - easy

King Julien, the ruler of all lemurs, has exactly 2⋅k lemurs under his command — two lemurs of each of the k species. Julien loves parties, so every evening he throws one. However, the VIP area unfortunately has room only for himself and n other lemurs.

Since Julien dislikes repeating himself, he wants to invite a set of lemurs to the VIP area that has never appeared before. Two lemurs of the same species are considered indistinguishable. Two sets of lemurs are considered the same if they coincide as multisets of species.

Help Julien determine how many distinct parties he can host. As the answer may be very large, print it modulo 109+7.

Input. A single line contains two integers k and n (1≤k≤500000, 0≤n≤2⋅k) — the number of lemur species and the number of available VIP seats (excluding Julien himself).

Output. Print one single integer — the number of distinct parties modulo 109+7.

Sample input 1
3 3
Sample output 1
7
Sample input 2
4 3
Sample output 2
16
Open problem
Solution

For n seats, some species will be represented by two lemurs, and some by one. Let i pairs of lemurs be chosen (that is, i species are represented by two individuals). The number of ways to make such a choice is Cki​. After this, there will be n−2i free seats in the VIP area. These seats can be occupied by lemurs from k−i remaining species, choosing one lemur from each. The number of ways to choose such lemurs is calculated by the formula Ck−in−2i​.

Since the value of i can take any integer from 0 to k, the final answer is obtained as the sum over all possible values of i:

i=0∑k​Cki​⋅Ck−in−2i​

Example

Let's consider a second example, where there are k=4 pairs of lemurs and n=3 seats in the VIP area. Using the formula, we get:

i=0∑k​C4i​⋅C4−i3−2i​=C40​⋅C43​+C41​⋅C31​=4+12=16

Let's list only the nonzero terms. We'll consider the value Cnk​ to be zero if any of the following three inequalities hold: k<0, n<0 или k>n.

Let us denote the lemurs by the letters {a,a,b,b,c,c,d,d}, where identical letters correspond to lemurs of the same species.

The term C40​⋅C43​=4 corresponds to the situation where no pair of lemurs of the same species is chosen, that is, each of the three selected lemurs belongs to a different species. The four possible selections are as follows:

Now consider the term C41​⋅C31​=12. In this case, two lemurs are chosen from one species (there are 4 possible ways to do this). For the remaining one seat, one lemur is chosen from the three remaining species. Thus, there are a total of 12 possible selections.

It is clear that it is impossible to place two lemurs from two different species in only 3 seats. Therefore, all the remaining terms of the sum are equal to zero.

Algorithm implementation

Declare the constants.

#define MAX 1000001
#define MOD 1000000007

Let us define the following arrays:

  • fact contains the factorials of numbers modulo MOD;

  • factinv contains the values inverse to the factorials of numbers modulo MOD:

fact[n] = n! mod 1000000007
factinv[n] = n! -1 mod 1000000007

typedef long long ll;
ll fact[MAX], factinv[MAX];

The function pow computes the power of a number modulo p: xn mod p.

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 function inverse finds the number that is the modular inverse of x with respect to a prime modulo p. Since p is a prime number, by Fermat's little theorem the following equality holds:

xp−1 mod p = 1 for every 1≤x<p

This equality can be rewritten as:

(x⋅xp−2) mod p = 1,

which means that the modular inverse of x is xp−2 mod p.

ll inverse(ll x, ll p)
{
  return pow(x, p - 2, p);
}

The function Cnk computes the value of the binomial coefficient using the following formula:

Cnk​=k!(n−k)!n!​
ll Cnk(int n, int k)
{
  return ((fact[n] * factinv[k]) % MOD * factinv[n - k]) % MOD;
}

The main part of the program. Read the input data.

scanf("%d %d", &k, &n);

Fill the factorial arrays fact and factinv.

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);
C++
7 lines
165 bytes

Compute the answer using the formula ∑i=0k​Cki​⋅Ck−in−2i​. The value of the binomial coefficient Cnk​ is considered to be zero if any of the following three conditions hold: k<0, n<0 or k>n.

res = 0;
for (i = 0; i <= k; i++)
{
  if (n - 2 * i < 0 || k - i < 0 || n - 2 * i > k - i) continue;
  res = (res + Cnk(k, i) * Cnk(k - i, n - 2 * i)) % MOD;
}

Print the answer.

printf("%lld\n", res);
Eolymp #973. Maximum sum on a tree

Given a tree with n vertices, where the vertex numbered i (1≤i≤n) contains ci​ coins. Select a subset of vertices such that no two of them are adjacent (i.e., connected by an edge), and the sum of coins in the selected vertices is maximized.

Input. The first line contains the number of vertices n (1≤n≤105) in a tree. Each of the next n−1 lines contains two integers u and v (1≤u,v≤n), defining an edge in the tree. The last line contains n non-negative integers c1​,...cn​ — the number of coins in each vertex of the tree.

Output. Print the maximum possible sum of coins that can be obtained by selecting a subset of vertices in the tree with no adjacent vertices.

Sample input 1
5
1 2
1 3
2 4
2 5
1 5 7 1 2
Sample output 1
12
Sample input 2
5
1 2
1 3
2 4
2 5
3 7 5 10 1
Sample output 2
16
Open problem
Solution

Let v be a vertex of the tree. Let's define:

  • dp1​(v) as the maximum sum of coins that can be collected from the subtree rooted at v if we take the coins in vertex v.

  • dp2​(v) as the maximum sum of coins that can be collected from the subtree rooted at v if we do not take the coins in vertex v.

Then the answer to the problem will be max(dp1​(1),dp2​(1)), assuming the first vertex is taken as the root of the tree.

Let’s define the given functions recursively:

  • If we take the coins in vertex v, then we cannot take coins from its children:

dp1​(v)=cv​+i=1∑k​dp2​(toi​),where to1​,...,tok​ are the sons of vertex v.
  • If we do not take the coins in vertex v, then we can choose either to take or not take coins from its children. We select the option with the maximum sum of coins:

dp2​(v)=i=1∑k​max(dp1​(toi​),dp2​(toi​)),where to1​,...,tok​ are the sons of vertex v.

If v is a leaf with cv​ coins, then the functions take the following values: dp1​(v)=cv​ and dp2​(v)=0.

Example

Let's assign the labels dp1​(v)/dp2​(v) to the vertices of the trees from the examples.

For the first example, we have:

  • dp1​(1)=c1​+dp2​(2)+dp2​(3)=1+3+0=4;

  • dp2​(1)=max(dp1​(2),dp2​(2))+max(dp1​(3),dp2​(3))=5+7=12;

  • dp1​(2)=c2​+dp2​(4)+dp2​(5)=5+0+0=5;

  • dp2​(2)=max(dp1​(4),dp2​(4))+max(dp1​(5),dp2​(5))=1+2=3;

For the second example, we have:

  • dp1(1)=c1​+dp2​(2)+dp2​(3)=3+11+0=14;

  • dp2​(1)=max(dp1​(2),dp2​(2))+max(dp1​(3),dp2​(3))=11+5=16;

  • dp1​(2)=c2​+dp2​(4)+dp2​(5)=7+0+0=7;

  • dp2​(2)=max(dp1​(4),dp2​(4))+max(dp1​(5),dp2​(5))=10+1=11;

Exercise

Assign the labels dp1​(v)/dp2​(v) to the vertices of the tree:

Algorithm implementation

Declare the arrays.

vector<vector<int> > g;
vector<int> dp1, dp2, cost;

The dfs function implements depth-first search. Compute the values of dp1​ and dp2​ at all vertices of the tree.

void dfs(int v, int p = -1)
{
  dp1[v] = cost[v];
  dp2[v] = 0;

  for (int to : g[v])
  {
    if (to == p) continue;

    dfs(to, v);

    dp1[v] += dp2[to];
    dp2[v] += max(dp1[to], dp2[to]);
  }
}
C++
15 lines
217 bytes

The main part of the program. Read the tree and the array of coins.

scanf("%d",&n);
g.resize(n+1);
for(i = 1; i < n; i++)
{
  scanf("%d %d",&u,&v);
  g[u].push_back(v);
  g[v].push_back(u);
}

dp1.resize(n+1); dp2.resize(n+1);
cost.resize(n+1);
for(i = 1; i <= n; i++)
  scanf("%d",&cost[i]);
C++
13 lines
238 bytes

Let the root of the tree be at vertex 1. Start the depth-first search from there.

dfs(1);

Compute and print the answer.

ans = max(dp1[1], dp2[1]);
printf("%d\n",ans);
Eolymp #11722. Rectangle Cutting

A rectangle of size a×b is given. Your task is to cut it into squares. In one move, you can select one of the rectangles and split it into two new rectangles so that all side lengths remain integers. Determine the minimum number of moves required to complete this task.

Input. Two integers a and b (1≤a,b≤500).

Output. Print the minimum number of moves required to cut the rectangle into squares.

Sample input 1
3 5
Sample output 1
3
Sample input 2
5 10
Sample output 2
1
Open problem
Solution

Let f(a,b) be the minimum number of moves required to cut a rectangle of size a×b into squares. We'll store this value in the cell dp[a][b].

If the rectangle is already a square (a=b), no cuts are needed, so f(a,a)=0.

A rectangle a×b can be cut either vertically or horizontally. Let's first consider a vertical cut.

With a vertical cut, the rectangle a×b is divided into two rectangles: a×k and a×(b−k). For the resulting rectangles to be non-degenerate, the condition 1≤k<b must hold. Then recursively solve the problem for each of these two rectangles and add 1 to the result, as we made one vertical cut. We choose such a k that minimizes the sum f(a,k)+f(a,b−k)+1:

f(a,b)=1≤k<b​min​(f(a,k)+f(a,b−k))+1

For a horizontal cut, we get a similar formula:

f(a,b)=1≤k<a​min​(f(k,b)+f(a−k,b)+1

It remains to choose the minimum value among these two options.

Example

In the first test, 3 cuts are required:

  • The first cut divides the 3×5 rectangle into 3×3 and 2×3;

  • The second cut divides the 2×3 rectangle into 2×2 and 2×1;

  • The third cut divides the 2×1 rectangle into 1×1 and 1×1;

Algorithm implementation

Let's declare constants and the array.

#define MAX 501
#define INF 0x3F3F3F3F

int dp[MAX][MAX];

The function f(a,b) returns the minimum number of moves required to cut a rectangle of size a×b into squares.

int f(int a, int b)
{

If the rectangle is already a square (a=b), no cuts are needed.

  if (a == b) return 0;

If the value of f(a,b) is not computed (dp[a][b]=∞), compute it.

  if (dp[a][b] == INF)
  {

Perform all possible vertical cuts.

    for (int k = 1; k < b; k++)
      dp[a][b] = min(dp[a][b], f(a, k) + f(a, b - k) + 1);

Perform all possible horizontal cuts.

    for (int k = 1; k < a; k++)
      dp[a][b] = min(dp[a][b], f(k, b) + f(a - k, b) + 1);
  }

Return the result f(a,b)=dp[a][b].

  return dp[a][b];
}

The main part of the program. Read the dimensions of the rectangle a and b.

scanf("%d %d", &a, &b);

Compute and print the answer.

memset(dp, 0x3F, sizeof(dp));
printf("%d\n", f(a, b));
Eolymp #1405. Sticks

The Law of the Jungle is very clear: every wolf, once he has started a family, may leave his Pack. But as soon as his cubs grow up and become strong enough, he must bring them to the Council of the Pack, which is usually held once a month during the full moon, and present them to all the other wolves.

Father Wolf waited until his cubs had grown a little and started to run about. Then, on one of the nights when the Pack gathered, he led them — together with Mowgli and Mother Wolf — to the Council Rock. It was the top of a hill strewn with large boulders, behind which a hundred wolves could easily hide. Akela, the great gray lone wolf, chosen as leader of the whole Pack for his strength and agility, called out from his rock:

— The Law is known to you, the Law is known to you! Look well, wolves!

Father Wolf pushed the Frog, Mowgli, into the center of the circle. Mowgli sat down on the ground, laughed, and began to play with some sticks.

He came up with a simple task: to make a rectangle of the maximum possible area from these sticks — not necessarily using all of them.

Input. The first line contains the number of sticks n (1≤n≤16). The second line contains their lengths — positive integers in the range from 1 to 108.

Output. Print the maximum possible area of a rectangle that can be made from the given set of sticks, or 0 if forming a rectangle is impossible.

Sample input
8
7 1 5 2 3 2 4 5 
Sample output
49
Open problem
Solution

Let S be the given set of sticks. It is required to find two disjoint subsets A and B of S such that the sticks in each of them can be divided into two subsets with equal total lengths.

For every subset mask⊆S, compute the total length of its sticks and store it in sum[mask].

Iterate over all subsets I⊂S. For each subset I, go through all of its subsets J⊂I. If there exists such a subset J that 2⋅sum[J]=sum[I] (that is, the total length of sticks in J is exactly half of the total length of sticks in I), then the subset I can be used as a pair of opposite sides of a rectangle. In this case, set can[I]=true.

The entire procedure runs in O(3n).

Iterate over all subsets of the set of sticks. If for some subset I there exists a subset J⊂I such that can[J]=true and can[I xor J]=true (that is, the subsets J and I xor J are disjoint), then we obtain one of the possible distributions of sticks between the horizontal and vertical sides of the rectangle.

The side lengths of such a rectangle are sum[J]/2 and sum[I xor J]/2. Among all such possible rectangles, choose the one with the maximum area.

Algorithm implementation

The lengths of the sticks are stored in the array a. For each subset of sticks mask, store their total length in the array sum[mask]. The value can[mask] is set to true if the subset mask can be divided into two parts with equal total lengths — these will correspond to the opposite sides of a rectangle.

#define MAX 16
int a[MAX];
int sum[1 << MAX];
bool can[1 << MAX];

The main part of the program. Read the input data.

scanf("%d",&n);
for (i = 0; i < n; i++)
  scanf("%d", &a[i]);

Iterate over all subsets of sticks and compute the total length of each subset.

for (i = 0; i < 1 << n; i++)
  for (j = 0; j < n; j++)
    if (i & (1 << j)) sum[i] += a[j];

Then, iterate through all possible subsets of the set of sticks. If for some subset I there exists a subset J⊂I such that the total length of sticks in J is exactly half of the total length of sticks in I, set can[I]=true. In this case, the sticks from subset I can be used as opposite sides of a rectangle.

for (i = 1; i < 1 << n; i++) 
{
  int s = sum[i];
  for (j = i; j > 0; j = (j - 1) & i)
    if (sum[j] * 2 == s) 
    {
      can[i] = true;
      break;
    }
}
C++
10 lines
172 bytes

Iterate over all subsets of the set of sticks. If for some subset I there exists a subset J⊂I such that can[J]=true and can[I xor J]=true, then we obtain one of the possible distributions of sticks between the horizontal and vertical sides of the rectangle. The side lengths of such a rectangle are sum[J]/2 and sum[IxorJ]/2.

res = 0;
for (i = 1; i < 1 << n; i++)
  for (j = i; j > 0; j = (j - 1) & i)
    if (can[j] && can[i ^ j])
      res = max(res, sum[j] / 2 * 1LL * sum[i ^ j] / 2);

Print the area of the rectangle with the maximum size found.

printf("%lld\n",res);
Eolymp #4073. Its a Murder!

Once, Detective Saikat was investigating a murder case. At the crime scene, he discovered a staircase with a number written on each step. Finding this suspicious, he decided to remember all the numbers he encountered along the way. Soon, he noticed a pattern: for each number on the staircase, he recorded the sum of all previously encountered numbers that were smaller than the current one.

Your task is to find the total sum of all numbers recorded by the detective in his notebook.

Input. The first line contains an integer t (t≤10) — the number of test cases. The next 2t lines follow. The first of these lines contains an integer n (1≤n≤105) — the number of steps. The next line contains n integers — the numbers written on the steps. All numbers are in the range from 0 to 106.

Output. For each test case, print the final sum in a separate line.

Sample input
1
5
1 5 3 6 4
Sample output
15
Open problem
Solution

The numbers written on the steps are integers and fall within the range from 0 to 106 inclusive.

We will construct a Fenwick tree on an array a of length 106+1 (with indices ranging from 0 to 106 inclusive), initially filled with zeros.

Each time the detective steps on a stair with the value value, we increase avalue​ by value. At the same time, he records the sum in his notebook:

a0​+a1​+a2​+...+avalue−1​

Given the input constraints, all calculations should be performed using a 64-bit integer type.

Example

Let's simulate the detective's recordings using the given example. The array indexing starts from 0. The numbers recorded by the detective are shown under the arrows.

The sum of the numbers written in the detective's notebook is

0+1+1+9+4=15
Algorithm implementation

Let the maximum array size be MAX. Create a Fenwick tree Fenwick.

#define MAX 1000001
vector<long long> Fenwick;

The function Summa0_i computes the sum a0​+a1​+...+ai​.

long long Summma0_i(int i)
{
  long long result = 0;
  for (; i >= 0; i = (i & (i + 1)) - 1)
    result += Fenwick[i];
  return result;
}
C++
7 lines
145 bytes

The function IncElement increases the value of an element: ai​=ai​+delta.

void IncElement(int i, int delta)
{
  for (; i < MAX; i = (i | (i+1)))
    Fenwick[i] += delta;
}

The main part of the program. Read the input data.

scanf("%d",&tests);
while (tests--)
{
  scanf("%d",&n);

Initialize the Fenwick array with zeros.

  Fenwick.assign(MAX,0);

The desired sum recorded in the detective's notebook will be computed in the variable sum.

  sum = 0;

Process the numbers written on the steps one by one.

  for (i = 0; i < n; i++)
  {

For each value, written on a step, increase avalue​ by value and compute the sum of all previously encountered numbers smaller than value. This sum is a0​+a1​+a2​+...+avalue−1​.

    scanf("%d",&value);
    IncElement(value, value);
    sum += Summma0_i(value - 1);
  }

Print the total sum of all numbers written in the detective's notebook.

  printf("%lld\n",sum);
}
Eolymp #10456. Server

Amin and Murad decided to create a Minecraft game server.

They invited k guests to the grand opening of the server. The guests live in different cities, and when connecting to the server, they will experience a certain latency (ping) depending on their location. Realizing the potential issues, Amin and Murad decided to choose the most optimal location for hosting the server.

There are n cities, numbered from 1 to n, and m bidirectional communication channels between them. A connection to the server is only possible through these channels. Using them, it is possible to establish a connection between any two cities. Each pair of cities may have at most one direct communication channel, and no city is connected to itself. Each channel has a transmission delay of wi​.

The connection delay between a city and the server is defined as the minimum possible sum of delays along the path from that city to the server.

Amin and Murad want to choose a city to host the server so that the total connection delay for all guests is minimized. If the server is hosted in the same city where a guest lives, the delay for that guest is considered to be zero.

If there are multiple cities with the same minimum total delay, Amin and Murad will choose the city with the smallest number.

Determine the city where the server will be hosted and the total connection delay for all guests to the server.

Input. The first line contains three integers n (1≤n≤104),m (1≤m≤4∗104), and k (1≤k≤100) — the number of cities, the number of communication channels, and the number of guests, respectively. The second line contains k distinct integers ci​ (1≤ci​≤n) — the numbers of the cities where the guests live.

Each of the following m lines contains three integers ui​,vi​, and wi​ (1≤ui​,vi​≤n) — describing a bidirectional communication channel between cities ui​ and vi​ with a delay of wi​ (1≤wi​≤104).

Output. Print two integers — the number of the city where the server will be hosted, and the total connection delay for all guests to this server.

Sample input
5 6 3
1 2 5
1 2 10
1 4 3
2 4 2
2 5 8
3 4 5
3 5 3
8 lines
57 bytes
Sample output
2 13
Open problem
Solution

Since n≤104, we will represent the graph using an adjacency list.

Run Dijkstra's algorithm from each city where a guest resides. For every vertex, compute the sum of distances to all guest cities.

The vertex with the smallest sum will be the optimal location for hosting the server. If there are multiple such vertices, choose the one with the smallest number.

Note that the server does not necessarily have to be placed in a city where one of the guests lives.

Example

The graph given in the example is as follows:

Run Dijkstra's algorithm from the vertices where the guests reside: 1,2, and 5. For each of these vertices, determine the shortest distances to all other cities.

Next, for each vertex of the graph, compute the sum of distances to all the cities with guests. The minimum sum of distances is 13, and it is achieved at the vertex with the smallest number 2.

Therefore, the server should be placed in city 2. The total distance from it to the cities where the guests reside is 5+0+8=13.

Algorithm implementation

Declare a constant for infinity.

#define INF 0x3F3F3F3F

The edge structure will store information about an edge: the vertex node that the edge leads to, and the weight dist of the edge.

struct edge
{
  int node, dist;
  edge(int node, int dist) : node(node), dist(dist) {}
};

Declare a comparator for sorting pairs (node,dist) in descending order of the dist value.

bool operator< (edge a, edge b)
{
  return a.dist > b.dist;
}

Declare an adjacency list to represent the graph.

vector<vector<edge> > g;

The Dijkstra function implements Dijkstra's algorithm. It takes the graph g and the starting vertex start as input. The return value is an array d, where d[i] contains the shortest distance from the vertex start to vertex i.

void Dijkstra(vector<vector<edge> >& g, vector<int>& d, int start)
{
  priority_queue<edge> pq;
  pq.push(edge(start, 0));

  d = vector<int>(n + 1, INF);
  d[start] = 0;

  while (!pq.empty())
  {
    edge e = pq.top(); pq.pop();
    int v = e.node;

    if (e.dist > d[v]) continue;

    for (auto e : g[v])
    {
      int to = e.node;
      int cost = e.dist;
      if (d[v] + cost < d[to])
      {
        d[to] = d[v] + cost;
        pq.push(edge(to, d[to]));
      }
    }
  }
}
C++
27 lines
513 bytes

The main part of the program. Read the input data.

scanf("%d %d %d", &n, &m, &k);
c.resize(k);
for (i = 0; i < k; i++)
  scanf("%d", &c[i]);

Read the input weighted graph.

g.resize(n + 1);
for (i = 0; i < m; i++)
{
  scanf("%d %d %d", &a, &b, &w);
  g[a].push_back(edge(b, w));
  g[b].push_back(edge(a, w));
}
C++
7 lines
145 bytes

Run Dijkstra's algorithm from the cities where the guests live.

dp.resize(n + 1);
for (i = 0; i < k; i++)
{
  Dijkstra(g, dist, c[i]);

  for (j = 1; j <= n; j++)
   dp[j] += dist[j];
}
C++
8 lines
130 bytes

Currently, dp[i] contains the sum of the shortest distances from vertex i to all the cities where the guests are located. The next step is to find the minimum value among the elements of the dp array and print the corresponding result. The variable ptr stores the smallest vertex number where the server should be placed.

res = INF;
for (i = 1; i <= n; i++)
{
  if (dp[i] < res)
  {
    res = dp[i];
    ptr = i;
  }
}
C++
9 lines
106 bytes

Print the answer.

printf("%d %d\n", ptr, dp[ptr]);

2

Comments

Loading

Just a moment, getting data from the server

Nothing yet

Be the first one to start the conversation!
Sign in