Educational Round #3 — Editorial
Find the maximum element of the array. Then, perform a second pass through the array to count the number of maximum elements.
Declare an array.
int m[101];
Read the input array. Find its maximum element .
scanf("%d", &n);
max = -2000000000;
for (i = 0; i < n; i++)
{
scanf("%d", &m[i]);
if (m[i] > max) max = m[i];
}In the variable , 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);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 — 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
1 2 3
1
Let 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 must be divisible by .
Let 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 passengers remain in each. This tranfer is only possible if a minibus initially contains more than passengers. For example, if , then passengers should be transferred from the first minibus. Similarly, passengers should be transferred from the second minibus (if ), and passengers from the third minibus (if ).
Read the input data.
scanf("%d %d %d",&a,&b,&c);If the total number of people is not divisible by , then print IMPOSSIBLE.
if((a + b + c) % 3 != 0)
puts("IMPOSSIBLE");
else
{
res = 0;Compute the number of people in minibuses after the transfer.
d = (a + b + c) / 3;
In the variable 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);
}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 — the number of remaining saucepans and lids. The second line contains integers — the radii of the remaining saucepans. The third line contains integers — the radii of the remaining lids.
Output. Print one number — the largest number of saucepans that can be covered by the available lids.
beginrow
5 5 4 8 1 2 5 7 2 4 6 5
4
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.
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);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 different types of items, with an unlimited number of each type available. The backpack can hold a maximum weight of . Each item of type has a weight of and a value of .
Input. The first line contains two positive integers and — the maximum weight the backpack can carry and the number of item types.
The next lines each contain two numbers and — the weight and value of an item of type .
Output. Print the maximum total value of the cargo that can be carried without exceeding the weight limit .
beginrow
10 2 5 10 6 19
20
Let be the maximum value of cargo with a weight of at most , considering only the first types of items.
Now, consider two possible options when forming cargo of weight :
Do not use an item of type : In this case, the optimal value remains unchanged, meaning:
Use an item of type : Then its weight will occupy part of the knapsack's capacity, and the value will increase by , meaning:
Since the goal is to maximize the cargo value, we obtain the following recurrence relation:
Base cases:
Let the function compute the maximum value of cargo that can be packed into a knapsack with a weight limit of , using the first types of items. Then, the next recurrence relation holds:
Finally, we need to compute the value of using memoization.
Declare the arrays:
— the weight of an item of type ;
— the value of an item of type ;
— the maximum value of cargo with a weight of at most ;
#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 types of items sequentially.
for (k = 0; k < n; k++)
{Update the values in the array, considering the possibility of using items of type . 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:
— the weight of an item of type ;
— the value of an item of type ;
— the maximum value of cargo with a weight of at most ;
#define MAXW 252 #define MAXN 37 #define INF 2000000000 int w[MAXN], v[MAXN]; int dp[MAXN][MAXW];
The function computes the maximum value of cargo that can be packed into a knapsack with a weight limit of , using the first types of items.
int f(int k, int s)
{If or , the knapsack is empty, and its value is .
if (k == 0 || s == 0) return 0;
If , we have exceeded the allowed weight, making this option invalid. Therefore, we return (where is a sufficiently large number).
if (s < 0) return -INF;
If the value of is already computed, return it.
if (dp[k][s] != -1) return dp[k][s];
Compute and store it in .
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));King Julien, the ruler of all lemurs, has exactly lemurs under his command — two lemurs of each of the species. Julien loves parties, so every evening he throws one. However, the VIP area unfortunately has room only for himself and 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 .
Input. A single line contains two integers and — 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 .
3 3
7
4 3
16
For seats, some species will be represented by two lemurs, and some by one. Let pairs of lemurs be chosen (that is, species are represented by two individuals). The number of ways to make such a choice is . After this, there will be free seats in the VIP area. These seats can be occupied by lemurs from remaining species, choosing one lemur from each. The number of ways to choose such lemurs is calculated by the formula .
Since the value of can take any integer from to , the final answer is obtained as the sum over all possible values of :
Example
Let's consider a second example, where there are pairs of lemurs and seats in the VIP area. Using the formula, we get:
Let's list only the nonzero terms. We'll consider the value to be zero if any of the following three inequalities hold: , или .
Let us denote the lemurs by the letters , where identical letters correspond to lemurs of the same species.
The term 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 . In this case, two lemurs are chosen from one species (there are 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 possible selections.
It is clear that it is impossible to place two lemurs from two different species in only seats. Therefore, all the remaining terms of the sum are equal to zero.
Declare the constants.
#define MAX 1000001 #define MOD 1000000007
Let us define the following arrays:
contains the factorials of numbers modulo ;
contains the values inverse to the factorials of numbers modulo :
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 : .
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 with respect to a prime modulo . Since is a prime number, by Fermat's little theorem the following equality holds:
This equality can be rewritten as:
which means that the modular inverse of is .
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:
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 and .
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);
Compute the answer using the formula . The value of the binomial coefficient is considered to be zero if any of the following three conditions hold: , or .
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);Given a tree with vertices, where the vertex numbered contains 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 in a tree. Each of the next lines contains two integers and , defining an edge in the tree. The last line contains non-negative integers — 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.
5 1 2 1 3 2 4 2 5 1 5 7 1 2
12
5 1 2 1 3 2 4 2 5 3 7 5 10 1
16
Let be a vertex of the tree. Let's define:
as the maximum sum of coins that can be collected from the subtree rooted at if we take the coins in vertex .
as the maximum sum of coins that can be collected from the subtree rooted at if we do not take the coins in vertex .
Then the answer to the problem will be , 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 , then we cannot take coins from its children:
If we do not take the coins in vertex , then we can choose either to take or not take coins from its children. We select the option with the maximum sum of coins:
If is a leaf with coins, then the functions take the following values: and .
Example
Let's assign the labels to the vertices of the trees from the examples.
For the first example, we have:
;
;
;
;
For the second example, we have:
;
;
;
;
Exercise
Assign the labels to the vertices of the tree:
Declare the arrays.
vector<vector<int> > g; vector<int> dp1, dp2, cost;
The dfs function implements depth-first search. Compute the values of and 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]);
}
}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]);Let the root of the tree be at vertex . Start the depth-first search from there.
dfs(1);
Compute and print the answer.
ans = max(dp1[1], dp2[1]);
printf("%d\n",ans);A rectangle of size 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 and .
Output. Print the minimum number of moves required to cut the rectangle into squares.
3 5
3
5 10
1
Let be the minimum number of moves required to cut a rectangle of size into squares. We'll store this value in the cell .
If the rectangle is already a square , no cuts are needed, so .
A rectangle can be cut either vertically or horizontally. Let's first consider a vertical cut.
With a vertical cut, the rectangle is divided into two rectangles: and . For the resulting rectangles to be non-degenerate, the condition must hold. Then recursively solve the problem for each of these two rectangles and add to the result, as we made one vertical cut. We choose such a that minimizes the sum :
For a horizontal cut, we get a similar formula:
It remains to choose the minimum value among these two options.
Example
In the first test, cuts are required:
The first cut divides the rectangle into and ;
The second cut divides the rectangle into and ;
The third cut divides the rectangle into and ;
Let's declare constants and the array.
#define MAX 501 #define INF 0x3F3F3F3F int dp[MAX][MAX];
The function returns the minimum number of moves required to cut a rectangle of size into squares.
int f(int a, int b)
{If the rectangle is already a square , no cuts are needed.
if (a == b) return 0;
If the value of is not computed , 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 .
return dp[a][b]; }
The main part of the program. Read the dimensions of the rectangle and .
scanf("%d %d", &a, &b);Compute and print the answer.
memset(dp, 0x3F, sizeof(dp));
printf("%d\n", f(a, b));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 . The second line contains their lengths — positive integers in the range from to .
Output. Print the maximum possible area of a rectangle that can be made from the given set of sticks, or if forming a rectangle is impossible.
8 7 1 5 2 3 2 4 5
49
Let be the given set of sticks. It is required to find two disjoint subsets and of such that the sticks in each of them can be divided into two subsets with equal total lengths.
For every subset , compute the total length of its sticks and store it in .
Iterate over all subsets . For each subset , go through all of its subsets . If there exists such a subset that (that is, the total length of sticks in is exactly half of the total length of sticks in ), then the subset can be used as a pair of opposite sides of a rectangle. In this case, set .
The entire procedure runs in .
Iterate over all subsets of the set of sticks. If for some subset I there exists a subset such that and (that is, the subsets and 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 and . Among all such possible rectangles, choose the one with the maximum area.
The lengths of the sticks are stored in the array . For each subset of sticks , store their total length in the array . The value is set to if the subset 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 there exists a subset such that the total length of sticks in is exactly half of the total length of sticks in , set . In this case, the sticks from subset 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;
}
}Iterate over all subsets of the set of sticks. If for some subset there exists a subset such that and , 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 and .
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);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 — the number of test cases. The next lines follow. The first of these lines contains an integer — the number of steps. The next line contains integers — the numbers written on the steps. All numbers are in the range from to .
Output. For each test case, print the final sum in a separate line.
1 5 1 5 3 6 4
15
The numbers written on the steps are integers and fall within the range from to inclusive.
We will construct a Fenwick tree on an array of length (with indices ranging from to inclusive), initially filled with zeros.
Each time the detective steps on a stair with the value , we increase by . At the same time, he records the sum in his notebook:
Given the input constraints, all calculations should be performed using a -bit integer type.
Example
Let's simulate the detective's recordings using the given example. The array indexing starts from . The numbers recorded by the detective are shown under the arrows.
The sum of the numbers written in the detective's notebook is
Let the maximum array size be . Create a Fenwick tree .
#define MAX 1000001 vector<long long> Fenwick;
The function Summa0_i computes the sum .
long long Summma0_i(int i)
{
long long result = 0;
for (; i >= 0; i = (i & (i + 1)) - 1)
result += Fenwick[i];
return result;
}The function IncElement increases the value of an element: .
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 array with zeros.
Fenwick.assign(MAX,0);
The desired sum recorded in the detective's notebook will be computed in the variable .
sum = 0;
Process the numbers written on the steps one by one.
for (i = 0; i < n; i++)
{For each , written on a step, increase by and compute the sum of all previously encountered numbers smaller than . This sum is .
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);
}Amin and Murad decided to create a Minecraft game server.
They invited 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 cities, numbered from to , and 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 .
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 , and — the number of cities, the number of communication channels, and the number of guests, respectively. The second line contains distinct integers — the numbers of the cities where the guests live.
Each of the following lines contains three integers , and — describing a bidirectional communication channel between cities and with a delay of .
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.
5 6 3 1 2 5 1 2 10 1 4 3 2 4 2 2 5 8 3 4 5 3 5 3
2 13
Since , 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: , and . 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 , and it is achieved at the vertex with the smallest number .
Therefore, the server should be placed in city . The total distance from it to the cities where the guests reside is .
Declare a constant for infinity.
#define INF 0x3F3F3F3F
The structure will store information about an edge: the vertex that the edge leads to, and the weight of the edge.
struct edge
{
int node, dist;
edge(int node, int dist) : node(node), dist(dist) {}
};Declare a comparator for sorting pairs in descending order of the 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 and the starting vertex as input. The return value is an array , where contains the shortest distance from the vertex to vertex .
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]));
}
}
}
}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));
}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];
}Currently, contains the sum of the shortest distances from vertex to all the cities where the guests are located. The next step is to find the minimum value among the elements of the array and print the corresponding result. The variable 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;
}
}Print the answer.
printf("%d %d\n", ptr, dp[ptr]);