Educational Round #8 — Editorial
Read the first term into the variable . Next, split the remaining line into pairs: an operator symbol and a term.
Sequentially read the pairs (character, number) until the end of the file, performing the corresponding operations.
Read the first term into the variable .
scanf("%d",&res);Read the operation sign (addition or subtraction), followed by an integer . Add to or subtract it from the total result .
while (scanf("%c%d", &ch, &x) == 2)
if (ch == '+') res += x; else res -= x;Print the result of the computations.
printf("%d\n",res);Algorithm implementation — iostream
Read the first term into the variable .
cin >> res;
Read the input data until the end of the file. Read the operation sign (either addition or subtraction) and the number that follows it.
while (cin >> ch >> x)
Add to or subtract from .
if (ch == '+') res += x; else res -= x;
Print the result of the computations.
cout << res << endl;
Stepan is interested in the greatest common divisor of a pair of numbers, namely . Given an integer , Stepan wants to know how many pairs of integers exist such that and .
Input. One integer .
Output. Print the number of such pairs.
1
1
4
8
Let's fix (for example ) and find the number of such that .
The values of that satisfy this equation are . So, any that is a divisor of satisfies the equation .
The number of such for which is equal to the number of divisors of . Since , we need to find the count of all divisors of numbers from to . In other words, we need to find the sum . However, calculating requires factoring the number , so direct computation of this sum takes time.
Let's look at the sum of divisors in a different way. Among the divisors of numbers from to , one appears times, two appears times, and so on (the divisor appears times). The number of required pairs of integers is
This sum can be computed in time.
Example
For we have the next pairs:
The number of pairs is
Read the value of .
scanf("%d",&n);Compute the answer using the formula and print it.
s = 0;
for (i = 1; i <= n; i++)
s += n / i;
printf("%d\n",s);A group of bandits has hidden a stolen treasure in a room. The door to the room should be unlocked only when it is necessary to take the treasure out. Since the bandits do not trust each other, they want to be able to open the room and take the loot only if at least of them agree to do so.
They decided to install several locks on the door in such a way that it opens only when all the locks are opened. Each lock may have up to keys, distributed among some subset of the bandits. A group of bandits can open a lock if and only if at least one member of the group possesses a key to that lock.
Given the values and , determine the minimum possible number of locks such that, with a proper distribution of keys every group consisting of at least bandits can open all the locks, while no group of smaller size can open all the locks.
For example, when and , it is sufficient to have locks. The keys to lock are given to bandits and , the keys to lock are given to bandits and , and the keys to lock are given to bandits and . No bandit can open all the locks alone, but any group of two bandits can open all of them. It is easy to see that two locks are not sufficient in this case.
Input. The first line contains the number of test cases. Each of the following lines corresponds to one test case and contains two integers and .
Output. For each test case, print the minimum number of required locks on a separate line.
4 3 2 5 1 10 7 5 3
3 1 210 10
Consider an arbitrary group of bandits. According to the conditions, this group must not be able to open the door. That means there must exist at least one lock for which none of these bandits has a key.
Therefore, for every subset of bandits of size , there must exist a corresponding lock whose keys are not given to any member of that subset.
Consider the following constructive key distribution algorithm:
For each subset of bandits of size , create one lock.
The keys to this lock are given to all the remaining bandits; that is, the keys are received by bandits.
The algorithm is correct because:
For a group of people, none of them has a key to their corresponding lock. Therefore, the door cannot be opened.
Now consider a group of people. Take any lock. It is "forbidden" only for one specific subset of bandits. In a group of people, there is necessarily at least one person outside this subset. Hence, the group has a key to every lock.
The minimum number of required locks is equal to , which is the number of subsets of size taken from a set of elements.
Example
Let there be bandits.
For , the number of locks is .
Lock | Subset | Keys |
1 | {} | 1, 2, 3, 4 |
Each bandit should be given a key to the single lock.
For , the number of locks is .
Lock | Subset | Keys |
1 | {1} | 2, 3, 4 |
2 | {2} | 1, 3, 4 |
3 | {3} | 1, 2, 4 |
4 | {4} | 1, 2, 3 |
The optimal distribution of locks among the bandits is as follows:
Any two bandits will be able to open all four locks and take the treasure.
For , the number of locks is .
Lock | Subset | Keys |
1 | {1, 2} | 3, 4 |
2 | {1, 3} | 2, 4 |
3 | {1, 4} | 2, 3 |
4 | {2, 3} | 1, 4 |
5 | {2, 4} | 1, 3 |
6 | {3, 4} | 1, 2 |
The optimal distribution of locks among the bandits is as follows:
Any two bandits will be missing the key to exactly one lock. Any three bandits will be able to open all six locks and take the treasure.
For , the number of locks is .
Lock | Subset | Keys |
1 | {1, 2, 3} | 4 |
2 | {1, 2, 4} | 3 |
3 | {1, 3, 4} | 2 |
4 | {2, 3, 4} | 1 |
The optimal distribution of locks among the bandits is as follows:
In order to open all four locks, each bandit must bring his single unique key.
Now consider the case . The number of locks is .
Lock | Subset | Keys | Lock | Subset | Keys | |
1 | {1, 2} | 3, 4, 5 | 6 | {2, 4} | 1, 3, 5 | |
2 | {1, 3} | 2, 4, 5 | 7 | {2, 5} | 1, 3, 4 | |
3 | {1, 4} | 2, 3, 5 | 8 | {3, 4} | 1, 2, 5 | |
4 | {1, 5} | 2, 3, 4 | 9 | {3, 5} | 1, 2, 4 | |
5 | {2, 3} | 1, 4, 5 | 10 | {4, 5} | 1, 2, 3 |
The optimal distribution of locks among the bandits is as follows:
In the cells we compute the values of the binomial coefficients .
#define MAX 31 long long cnk[MAX][MAX];
The function FillCnk fills the array with the values of the binomial coefficients.
void FillCnk(void)
{
memset(cnk,0,sizeof(cnk));
for (int n = 0; n < MAX; n++) cnk[n][0] = 1;
for (int n = 1; n < MAX; n++)
for (int k = 1; k <= MAX; k++)
cnk[n][k] = cnk[n-1][k] + cnk[n-1][k-1];
}The main part of the program. Call the function FillCnk.
FillCnk();
Read the number of test cases .
scanf("%d",&tests);
while (tests--)
{Read the input data for the current test case and print the answer.
scanf("%d %d",&n,&m);
printf("%lld\n",cnk[n][m-1]);
}Along the beautiful Adriatic coast, there are hotels. Each hotel has its cost in euros.
Petr won euros in the lottery. Now he wants to buy a sequence of consecutive hotels one after another so that the sum of the costs of these consecutive hotels is as large as possible, but does not exceed .
You need to calculate this maximum possible total cost.
Input. The first line contains two integers and . The next line contains positive integers less than , representing the costs of the hotels in the order they are located along the coast.
Output. Print the desired maximum cost (it will be greater than in all tests).
5 12 2 1 3 4 5
12
Store the hotel costs in the array. We’ll call the interval good if the sum of hotel costs within it does not exceed .
Let’s implement a sliding window using two indices and , and maintain it so that the current interval is good. Let be the sum of hotel costs within the interval . If , then expand the current interval to . Otherwise, shrink it to . Find the maximum among the costs of all considered good intervals.
Example
Consider the movement of pointers for the given example.
When moves forward until the sum of numbers in the interval does not exceed . Stop at the interval because the sum there is equal to , while the sum in the interval is equal to .
When , we cannot move forward because the sum in the interval is equal to .
When move forward to the interval .
The maximum value among all good intervals is equal to and is achieved in the interval .
Read the input data.
scanf("%d %lld", &n, &m);Initialize the variables:
in , the maximum value among the costs of all processed good intervals is computed;
in , the sum of numbers in the current interval is maintained. All the numbers in the current interval are stored in the queue ;
s = res = 0;
Process the hotel costs sequentially.
for (i = 0; i < n; i++)
{Read and add the cost of the current hotel to the queue.
scanf("%d", &val);
q.push(val);Update the sum within the interval. All elements of the current interval are stored in the queue .
s += val;
If the sum of numbers in the current interval exceeds , we remove elements from the beginning of the interval.
while (s > m)
{
s -= q.front();
q.pop();
}Compute the maximum value among the sums of elements in good intervals (where the cost of hotels does not exceed ).
if (s > res) res = s; }
Print the answer.
printf("%lld\n", res);Probability is often an integral part of computer algorithms. When deterministic algorithms are unable to solve a problem within a reasonable amount of time, probabilistic algorithms come to the rescue. However, in this problem you are not required to design a probabilistic algorithm — you only need to compute the probability that a particular player wins the game.
The game involves players who take turns throwing an object similar to a die (the number of faces is not necessarily six). The players move in order: first the first player, then the second, and so on up to the -th player. If in a given round none of the players wins, the game continues again starting from the first player.
A player wins if, during their turn, a certain event occurs (for example, the number is rolled, a green face appears, and so on), after which the game ends immediately. The probability that this winning event occurs in a single throw is .
Determine the probability that the player with number wins.
Input. The first line contains a single integer — the number of test cases. Each of the following lines contains three values: the number of players , a real number — the probability of the winning event in a single throw, and the player number for which the winning probability should be computed.
Output. For each test case, print the probability that the -th player wins. The answer should be printed with exactly digits after the decimal point.
2 2 0.166666 1 2 0.166666 2
0.5455 0.4545
Let us consider the game from the perspective of probability theory:
Each throw is independent of the others;
The probability of winning on a single throw is ;
The probability of failure on a single throw is ;
The players take turns in a cycle: ;
The game ends immediately as soon as someone wins.
We are interested in the probability that the -th player wins.
The fact that the -th player wins means that:
no one has won before his winning throw;
the winning event occurs on his turn.
Moreover, the -th player may win:
on his first throw;
on his second throw;
on his third throw;
and so on.
The final probability is equal to the sum of the probabilities of all these cases.
For the -th player to win on his first turn, two conditions must be satisfied:
The first players do not win. The probability of this event is
The -th player wins. The probability of this event is .
Since the events are independent, the probability that the -th player wins on his first turn is equal to
The -th player wins on his second turn if:
All players make one throw each and lose:
The first players lose again in the second round. The probability of this event is .
The -th player wins. The probability of this event is .
The probability that the -th player wins on his second turn is equal to
By reasoning in the same way, we obtain that the probability for the -th player to win on his -th turn is equal to
Now it remains to sum the obtained probabilities. The overall probability that the -th player wins is equal to
The expression in parentheses is an infinite geometric progression with first term equal to and common ratio . The winning probability is equal to
It should be noted separately that when , the answer is .
Read the input data.
scanf("%d",&t);
while(t--)
{
scanf("%d %lf %d",&n,&p,&i);If the probability is equal to , print .
if (p == 0) printf("0\n");
else
{Otherwise, compute the required probability using the formula given above. Print the result with digits after the decimal point.
res = p * pow(1 - p,i - 1) / (1 - pow(1 - p,n));
printf("%.4lf\n",res);
}
}Washing clothes in winter is no easy task, and drying them is even more challenging. But Jane is a clever girl and isn't afraid of routine chores. To speed up the drying process, she decided to use a radiator. However, the radiator is small and can dry only one item at a time.
Jane wants to dry the laundry as quickly as possible. She's asking you to write a program that determines the minimum amount of time needed to dry the entire set of clothes.
Jane has just washed items. During the wash, each item absorbed units of water. Every minute, the amount of water in each item decreases by (as long as the item is not yet dry). Once the amount of water reaches , the item is considered dry and can be packed.
Additionally, each minute, Jane can choose one item and place it on the radiator. The radiator is hot enough that an item placed on it loses units of water per minute (but no more than the amount of water it contains: if an item has less than units of water, it simply dries completely in that minute).
Your task is to determine the minimum amount of time needed to dry all the clothes with optimal use of the radiator. Drying is considered complete when all items are fully dry.
Input. The first line contains one integer — the number of items.
The second line contains integers , where is the amount of water in the -th item after washing.
The third line contains one integer — the evaporation rate of water from an item placed on the radiator (in units of water per minute).
Output. Print one integer — the minimum number of minutes required to completely dry all items.
3 2 3 9 5
3
3 2 3 6 5
2
Let be the largest value among all . Obviously, after minutes, all the laundry will dry naturally, even without using the radiator.
Let the answer be a value . This means that all items containing at most units of water will have enough time to dry naturally. Any item that contains more than units of water will require additional drying on the radiator.
We assume that each item loses unit of water per minute, regardless of whether it is on the radiator or not. However, if an item is placed on the radiator, it loses an additional units of water per minute, meaning it loses units per minute in total.
If minutes are enough to dry all the items, then each item with must be additionally dried using the radiator. The amount of water that won't evaporate naturally is . Since the radiator removes extra units of water per minute, this item will require
minutes of radiator time.
The total number of minutes the radiator is used must not exceed , since only one item can be dried per minute. The summation is taken over all indices i for which .
Thus, the check is performed as follows: if, for a given value of , the total required radiator time does not exceed , then this value of is considered valid. The smallest valid value of can be found using binary search.
Example
Initially, there are three items with water amounts: .
In the first minute, place the third item on the radiator. The state becomes: .
In the second minute, again place the third item on the radiator. The state becomes: .
In the third minute, the second item dries naturally. The final state is: .
Let's consider the value . In this case, all items containing no more than units of water will dry naturally.
The remaining items will require drying using the radiator.
The second item contains units of water, so the radiator needs to remove unit.
The third item contains units of water, so the radiator needs to remove units.
This will take minutes. This exceeds , so two minutes are not enough.
Declare the array.
#define MAX 100001 int a[MAX];
Read the input data.
scanf("%d",&n);
for(i = 0; i < n; i++) scanf("%d",&a[i]);
scanf("%d",&k);In minutes, all the laundry will definitely dry, even without using the radiator.
l = 0; r = *max_element(a,a+n);
If , then drying with the radiator is equivalent to natural drying, and the radiator provides no advantage.
if (k <= 1)
{
printf("%d\n",r); return 0;
}The minimum required number of minutes can be found using binary search on the interval .
while (r - l > 1)
{
m = (r + l) / 2;The variable accumulates the total number of minutes during which the radiator needs to be used. All the laundry must be dried within minutes.
dry = 0;
for (i = 0; i < n; i++)
{
if (a[i] > m)
dry += (a[i] - m + k - 2) / (k - 1);
if (dry > m) break;
}
if (dry > m) l = m; else r = m;
}Print the answer.
printf("%d\n",r);On clear summer days, Nyusha enjoys catching butterflies in the fresh air. But today, she encountered a particularly cunning butterfly — it flew into a labyrinth and tried to hide from her inside.
The labyrinth consists of rooms, numbered from to , some of which are connected by corridors. It is known that there is exactly one simple path between any two rooms, passing only through the corridors. In other words, the labyrinth forms a tree with vertices and edges.
The entrance to the labyrinth is located in room number . A leaf is defined as any room connected to exactly one other room and not being the root (i.e., not room ). Each leaf contains an exit from the labyrinth. The butterfly starts its flight from room , heading toward one of the exits. It moves at a constant speed, never turns around, and travels through one corridor per minute, moving to a neighboring room. All corridors are of equal length.
To catch the butterfly, Nyusha decided to enlist the help of some friends. Initially, each of them can take position in any room that contains an exit. As soon as the butterfly begins its journey from the entrance toward some exit, the friends may immediately start moving from their rooms toward the entrance. They move at the same speed as the butterfly. If any of them encounters the butterfly — whether in a room or in the middle of a corridor — it is considered caught. However, if the butterfly reaches an exit without encountering any of the friends, it successfully escapes to freedom.
Help Nyusha determine the minimum number of friends needed to guarantee catching the butterfly, regardless of which exit it chooses.
Input. The first line contains a single integer — the number of rooms in the labyrinth.
The following lines describe the corridors connecting the rooms. Each line contains two integers and — the indices of the rooms connected by a corridor.
It is guaranteed that the given corridor system forms a tree.
Output. Print a single integer — the minimum number of friends required to guarantee that the butterfly will be caught.
3 1 2 1 3
2
4 1 2 2 3 2 4
1
Perform a depth-first search starting from vertex . For each vertex, compute two values:
— the distance from vertex to vertex . If is the parent of , then
— the distance from vertex v to the nearest leaf in the subtree rooted at . If are the children of vertex , then
If is a leaf of the tree, set .
Next, perform a second depth-first search. During this traversal, compute the value — the minimum number of friends that need to be placed in some of the leaves of the subtree rooted at vertex in order to guarantee catching the butterfly, assuming it chooses to fly into this subtree.
If , then . In this case, it is enough to place one friend in the leaf with the minimal depth in the subtree rooted at vertex : they will reach vertex no later than the butterfly flying from the root.
Otherwise, if are the children of vertex , then
If the butterfly is not caught at vertex itself, we must be prepared to intercept it in any of the subtrees of 's children.
The final answer to the problem is the value .
Example
In the first example (shown in the left diagram), two friends are required, and they should be placed at the two exits. The butterfly can fly from vertex either to vertex or to vertex . In either case, it will be intercepted by one of Nyusha's friends.
In the second example (shown in the right diagram), one friend is enough, who can be placed at either of the two exits — vertex or . The butterfly will fly from vertex to vertex in one minute. During that same time, the friend will reach vertex and catch the butterfly there.
Let us consider the next example.
Nyusha will need three friends to catch the butterfly.
Declare a constant for infinity and arrays.
#define INF 2000000000 vector<vector<int> > g; vector<int> d, h, res;
The function dfs performs a depth-first search starting from vertex and returns the value . Here, is the parent of vertex , and cnt is the distance from vertex to . During the traversal, the values and are computed for each vertex .
int dfs(int v, int p = -1, int cnt = 0)
{The value , which equals the distance from vertex to , is stored in .
d[v] = cnt; int height = INF;
Iterate over all the children of the vertex . Consider the edge . If equals the parent of , skip it and move to the next child.
for (int to : g[v])
if (to != p) In the variable compute the value
where are the children of vertex .
If , then vertex is a leaf, and set . Otherwise rerturn
return h[v] = (height == INF) ? 0 : 1 + height; }
The function dfs2 performs a depth-first search starting from vertex and returns the value . Here, is the parent of vertex .
int dfs2(int v, int p = -1)
{
int s = 0;Let be the children of vertex . In the variable , compute the sum:
for (int to : g[v])
if (to != p)
{
dfs2(to, v);
s += res[to];
}If , then one friend is sufficient, and . Otherwise
return res[v] = (h[v] <= d[v]) ? 1 : s; }
The main part of the program. Read the input data. Construct a graph.
scanf("%d", &n);
g.resize(n + 1);
for (i = 0; i < n - 1; i++)
{
scanf("%d %d", &a, &b);
g[a].push_back(b);
g[b].push_back(a);
}Initialize the arrays.
d.resize(n + 1); h.resize(n + 1); res.resize(n + 1);
Run two depth-first searches. The first traversal computes the values of and for each vertex .
dfs(1); dfs2(1);
Print the answer — the minimum number of friends needed to catch the butterfly.
printf("%lld\n", res[1]);A connected graph that contains no cycles is called a tree.
The distance between two vertices of a tree is defined as the length (in edges) of the shortest path connecting them.
Given a tree with vertices and a positive integer , calculate the number of distinct pairs of vertices in the tree whose distance is exactly . Note that the pairs and are considered the same.
Input. The first line contains two integers and — the number of vertices in the tree and the required distance between vertices.
Each of the following lines describes an edge of the tree in the format , where and are the vertices connected by the -th edge. All edges are distinct.
Output. Print one integer — the number of distinct pairs of vertices in the tree whose distance is exactly .

5 2 1 2 2 3 3 4 2 5
4
Let denote the number of vertices at distance from vertex in the subtree rooted at . Set , since the only vertex at distance from is itself.
Suppose that vertex has children . Then the number of vertices at distance from vertex in the subtree rooted at is equal to the sum of the numbers of vertices at distance from each of the vertices .
Consider the subtree rooted at vertex . Let's count the number of paths of length that lie entirely within this subtree and pass through vertex . We divide such paths into two groups:
paths that start at vertex . Their number is equal to .
paths that pass through vertex and whose endpoints are located in the subtrees of the children of vertex .
Consider a path of length that passes through the root of the subtree . Let the distance from vertex to one end of the path be . Suppose this end lies in the subtree of some child . Then the distance from to the other end of the path is , and this other end can be located in any other subtree except the subtree rooted at .
If the distance from the first end of the path to vertex is , then the distance from this end to vertex is . The number of ways to choose such a first end is .
The number of ways to choose the second end of the path is equal to the number of vertices at distance from vertex that do not belong to the subtree rooted at . This number is
According to the multiplication principle, the total number of such paths is
Thus, the total number of such paths is
It remains to sum the above expression over all vertices of the tree.
Example
Consider the tree presented in the example.
The array stores the tree representation in the form of adjacency lists. The array is used to implement dynamic programming.
vector<vector<int> > g; vector<vector<int> > dp;
The function dfs performs a depth-first search starting from vertex . The value denotes the parent of vertex . During the traversal, the array is constructed.
void dfs(int v, int p = -1)
{Initialize the array .
dp[v].resize(k+1); dp[v][0] = 1;
Iterate over all vertices that can be reached from vertex .
for (int to : g[v])
{
if (to == p) continue;
dfs(to,v);
for(int x = 1; x <= k; x++)
dp[v][x] += dp[to][x-1];
}
}The function dfsRes performs a depth-first search starting from vertex and is intended to compute the desired answer.
void dfsRes(int v, int p = -1)
{
for (int to : g[v])
{
if (to == p) continue;
dfsRes(to,v);
for(int x = 1; x < k; x++)
resA += 1LL * dp[to][x-1] * (dp[v][k-x] - dp[to][k-x-1]);
}
resB += dp[v][k];
}The main part of the program. Read the input data. Build the tree.
scanf("%d %d",&n,&k);
g.resize(n+1);
for (i = 0; i < n - 1; i++)
{
scanf("%d %d",&a,&b);
g[a].push_back(b);
g[b].push_back(a);
}Using the first depth-first search, construct the array.
dp.resize(n+1); dfs(1);
Compute and print the required answer.
resA = resB = 0;
dfsRes(1);
res = resA / 2 + resB;
printf("%lld\n",res);Let us call a string of length greater than one a palindrome if it reads the same from left to right and from right to left.
A superpalindrome is a string that can be represented as a concatenation of one or more palindromes.
Given a string , find the number of substrings of that are superpalindromes.
Input. One string consisting of lowercase Latin letters.
Output. Print one integer — the number of substrings of the string that are superpalindromes.
abc
0
abacdc
3
Let be the input string. A substring is a palindrome if at least one of the following conditions is satisfied:
, that is, the substring is empty or consists of a single character;
and the substring is a palindrome;
Let's define the function IsPal, that returns if the substring is a palindrome, and otherwise.
To speed up the algorithm, the values of are stored in the cells of a two-dimensional array .
A string is called a superpalindrome if it can be represented as a concatenation of one or more palindromes. For example, the following strings are superpalindromes:
Let
Here it is assumed that , that is, the length of the substring is at least two.
Let us note the base cases:
If , then the substring is either empty or consists of a single character. Such strings are not considered palindromes by definition. Therefore,
In particular, for any position , we have .
If the substring is a palindrome and its length is at least two, then it is automatically a superpalindrome (since it consists of a single palindrome). Therefore, for all pairs of indices where , if the substring is a palindrome, we can immediately set .
Now consider the general case. Let the substring not be a palindrome as a whole. It can still be a superpalindrome if it can be split into two parts, each of which is a superpalindrome.
To do this, iterate over all possible split positions such that .
The restriction ensures that both substrings
have length at least two, and therefore can potentially be superpalindromes.
If, for some , the following conditions are satisfied:
,
,
then the substring can be represented as a concatenation of two superpalindromes. Therefore, it is itself a superpalindrome, and we set .
If this condition is not satisfied for any valid , then remains .
Finally, count the number of pairs for which and . This count is exactly the number of substrings of the string that are superpalindromes.
Example
For the given example — the string "" — there are substrings that are superpalindromes:
For the string "", there are substrings that are superpalindromes:
Declare the arrays.
#define MAX 1010 char s[MAX]; int dp[MAX][MAX]; int pal[MAX][MAX];
The function IsPal checks whether the substring is a palindrome. The substring is a palindrome if and the substring is also a palindrome. The values of the function IsPal are stored in the cells of the two-dimensional array .
int IsPal(int i, int j)
{
if (i >= j) return pal[i][j] = 1;
if (pal[i][j] != -1) return pal[i][j];
return pal[i][j] = (s[i] == s[j]) && IsPal(i + 1,j - 1);
}The main part of the program. Read the input string and compute its length .
cin >> s; n = s.size();
Initialize the arrays and .
memset(dp,0,sizeof(dp)); memset(pal,-1,sizeof(pal));
Iterate over all substrings of the string in increasing order of their length . This is important because the value of depends on the values for shorter substrings.
for (len = 1; len < n; len++)
for (i = 0; i + len < n; i++)
{The right boundary of the substring is .
j = i + len;
If the substring is a palindrome, then it is automatically also a superpalindrome.
if (IsPal(i,j))
{
dp[i][j] = 1;
continue;
}If the substring is not a palindrome, we try to represent it as a concatenation of two superpalindromes.
If and are superpalindromes, then is a superpalindrome as well.
for (k = i + 1; k < j - 1; k++)
if (dp[i][k] && dp[k + 1][j])
{
dp[i][j] = 1;
break;
}
}Count the number of superpalindromes. It is equal to the number of index pairs (i, j) for which dp[i][j] = 1.
res = 0; for (i = 0; i < n; i++) for (j = i + 1; j < n; j++) res += dp[i][j];
Print the answer.
printf("%d\n",res);Algorithm implementation – recursion
Declare the input string and arrays.
#define MAX 1010 string s; int dp[MAX][MAX], pal[MAX][MAX];
The function IsPal checks whether the substring is a palindrome. The substring is a palindrome if and the substring is also a palindrome. The values of the function IsPal are stored in the cells of the two-dimensional array .
int IsPal(int i, int j)
{
if (i >= j) return pal[i][j] = 1;
if (pal[i][j] != -1) return pal[i][j];
return pal[i][j] = (s[i] == s[j]) && IsPal(i+1,j-1);
}The function f returns if the substring is a superpalindrome.
int f(int i, int j)
{A superpalindrome must contain more than one character.
if (i == j) return dp[i][j] = 0;
If the value of f is already computed, return this value.
if (dp[i][j] != -1) return dp[i][j];
If the substring is a palindrome, then it is also a superpalindrome.
if (IsPal(i,j)) return dp[i][j] = 1;
If the substring is a palindrome and the substring is a superpalindrome, then the substring is a superpalindrome.
for (int k = i + 1; k < j - 1; k++)
if (IsPal(i,k) && f(k + 1,j)) return dp[i][j] = 1;If none of the conditions described above is satisfied, then the substring is not a superpalindrome.
return dp[i][j] = 0; }
The main part of the program. Read the input string and compute its length .
cin >> s; n = s.size();
Initialize the arrays and .
memset(dp,-1,sizeof(dp)); memset(pal,-1,sizeof(pal));
In the variable count the number of superpalindromes.
res = 0; for (i = 0; i < n; i++) for (j = i + 1; j < n; j++) res += f(i,j);
Print the answer.
cout << res << endl;