0% found this document useful (0 votes)
691 views272 pages

Atcoder - Editorials From 29-07-2023 To 19-08-2023 (6 Weeks)

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
691 views272 pages

Atcoder - Editorials From 29-07-2023 To 19-08-2023 (6 Weeks)

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 272

A DETAILED EDITORIAL FOR

ATCODER - FREEE PROGRAMMING CONTEST 2023


(ATCODER BEGINNER CONTEST 310)

Date of Contest: 15-07-2023

Editorial by
Dr. Dinesh Kumar Anguraj, Asso. Prof., Dept. of CSE.
Website Link: https://atcoder.jp/

Contest URL: https://atcoder.jp/contests/abc310

Mode: Rated & Unrated

Number of Contest Tasks: 7 Tasks

Number of Extra Tasks: 1 Task

Note & Credits: Problem statement and Hints from Atcoder.jp by a user
“en_translator”
CONTEST PROBLEM
STATEMENTS
A - Order Something Else

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 100 points

Problem Statement
Takahashi wants a beverage called AtCoder Drink in a restaurant. It can be ordered at a regular price of P
yen.

He also has a discount coupon that allows him to order it at a lower price of Q yen. However, he must
additionally order one of the restaurant's N dishes to use that coupon. For each i = 1, 2, … , N , the
price of the i-th dish is Di yen.

Print the minimum total amount of money that he must pay to get the drink.

Constraints
1 ≤ N ≤ 100
1 ≤ Q < P ≤ 105
1 ≤ Di ≤ 105

All input values are integers.

Input
The input is given from Standard Input in the following format:

N P Q
D1 D2 … DN
​ ​ ​

Output
Print the answer.

Sample Input 1
3 100 50
60 20 40
Sample Output 1
70

If he uses the coupon and orders the second dish, he can get the drink by paying 50 yen for it and 20 yen
for the dish, for a total of 70 yen, which is the minimum total payment needed.

Sample Input 2
3 100 50
60000 20000 40000

Sample Output 2
100

The total payment will be minimized by not using the coupon and paying the regular price of 100 yen.
B - Strictly Superior

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 200 points

Problem Statement
AtCoder Shop has N products. The price of the i-th product (1 ≤ i ≤ N ) is Pi . The i-th product (1 ≤

i ≤ N ) has Ci functions. The j -th function (1 ≤ j ≤ Ci ) of the i-th product (1 ≤ i ≤ N ) is


​ ​

represented as an integer Fi,j between 1 and M , inclusive. ​

Takahashi wonders whether there is a product that is strictly superior to another. If there are i and j
(1 ≤ i, j ≤ N ) such that the i-th and j -th products satisfy all of the following conditions, print Yes;
otherwise, print No.

Pi ≥ Pj .
​ ​

The j -th product has all functions of the i-th product.


Pi > Pj , or the j -th product has one or more functions that the i-th product lacks.
​ ​

Constraints
2 ≤ N ≤ 100
1 ≤ M ≤ 100
1 ≤ Pi ≤ 105  (1 ≤ i ≤ N )

1 ≤ Ci ≤ M  (1 ≤ i ≤ N )​

1 ≤ Fi,1 < Fi,2 < ⋯ < Fi,Ci ≤ M  (1 ≤ i ≤ N )


​ ​


All input values are integers.

Input
The input is given from Standard Input in the following format:

N M
P1 C1 F1,1 F1,2 … F1,C1
​ ​ ​ ​


P2 C2 F2,1 F2,2 … F2,C2


​ ​ ​ ​



PN CN FN ,1 FN ,2 … FN ,CN
​ ​ ​ ​


Output
Print the answer in a single line.
Sample Input 1
5 6
10000 2 1 3
15000 3 1 2 4
30000 3 1 3 5
35000 2 1 5
100000 6 1 2 3 4 5 6

Sample Output 1
Yes

(i, j) = (4, 3) satisfies all of the conditions.


No other pair satisfies them. For instance, for (i, j) = (4, 5), the j -th product has all functions of the i-
th one, but Pi ​ < Pj , so it is not strictly superior.

Sample Input 2
4 4
3 1 1
3 1 2
3 1 2
4 2 2 3

Sample Output 2
No

Multiple products may have the same price and functions.


Sample Input 3
20 10
72036 3 3 4 9
7716 4 1 2 3 6
54093 5 1 6 7 8 10
25517 7 3 4 5 6 7 9 10
96930 8 2 3 4 6 7 8 9 10
47774 6 2 4 5 6 7 9
36959 5 1 3 4 5 8
46622 7 1 2 3 5 6 8 10
34315 9 1 3 4 5 6 7 8 9 10
54129 7 1 3 4 6 7 8 9
4274 5 2 4 7 9 10
16578 5 2 3 6 7 9
61809 4 1 2 4 5
1659 5 3 5 6 9 10
59183 5 1 2 3 4 9
22186 4 3 5 6 8
98282 4 1 4 7 10
72865 8 1 2 3 4 6 8 9 10
33796 6 1 3 5 7 9 10
74670 4 1 2 6 8

Sample Output 3
Yes
C - Reversible

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 300 points

Problem Statement
There are N sticks with several balls stuck onto them. Each ball has a lowercase English letter written on
it.

For each i = 1, 2, … , N , the letters written on the balls stuck onto the i-th stick are represented by a
string Si . Specifically, the number of balls stuck onto the i-th stick is the length ∣Si ∣ of the string Si , and
​ ​ ​

Si is the sequence of letters on the balls starting from one end of the stick.

Two sticks are considered the same when the sequence of letters on the balls starting from one end of one
stick is equal to the sequence of letters starting from one end of the other stick. More formally, for
integers i and j between 1 and N , inclusive, the i-th and j -th sticks are considered the same if and only if
Si equals Sj or its reversal.
​ ​

Print the number of different sticks among the N sticks.

Constraints
N is an integer.
2 ≤ N ≤ 2 × 105
Si is a string consisting of lowercase English letters.

∣Si ∣ ≥ 1 ​

5
∑N i=1 ∣Si ∣ ≤ 2 × 10 ​ ​

Input
The input is given from Standard Input in the following format:

N
S1 ​

S2 ​


SN ​

Output
Print the answer.
Sample Input 1
6
a
abc
de
cba
de
abc

Sample Output 1
3

S2 = abc equals the reversal of S4 = cba, so the second and fourth sticks are considered the same.
​ ​

S2 = abc equals S6 = abc, so the second and sixth sticks are considered the same.
​ ​

S3 = de equals S5 = de, so the third and fifth sticks are considered the same.
​ ​

Therefore, there are three different sticks among the six: the first, second (same as the fourth and sixth),
and third (same as the fifth).
D - Peaceful Teams

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 400 points

Problem Statement
There are N sports players.

Among them, there are M incompatible pairs. The i-th incompatible pair (1 ≤ i ≤ M ) is the Ai -th and

Bi -th players.

You will divide the players into T teams. Every player must belong to exactly one team, and every team
must have one or more players. Additionally, for each i = 1, 2, … , M , the Ai -th and Bi -th players must
​ ​

not belong to the same team.

Find the number of ways to satisfy these conditions. Here, two divisions are considered different when
there are two players who belong to the same team in one division and different teams in the other.

Constraints
1 ≤ T ≤ N ≤ 10
N (N − 1)
0≤M ≤
2

1 ≤ Ai < Bi ≤ N  (1 ≤ i ≤ M )
​ ​

(Ai , Bi ) 
​ = (Aj , Bj ) (1 ≤ i < j ≤ M )
​ ​

All input values are integers.

Input
The input is given from Standard Input in the following format:

N T M
A1 B1
​ ​

A2 B2
​ ​


AM BM​ ​

Output
Print the answer in a single line.
Sample Input 1
5 2 2
1 3
3 4

Sample Output 1
4

The following four divisions satisfy the conditions.

No other division satisfies them, so print 4.

Sample Input 2
5 1 2
1 3
3 4

Sample Output 2
0

There may be no division that satisfies the conditions.


Sample Input 3
6 4 0

Sample Output 3
65

There may be no incompatible pair.

Sample Input 4
10 6 8
5 9
1 4
3 8
1 6
4 10
5 7
5 6
3 7

Sample Output 4
8001
E - NAND repeatedly

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 450 points

Problem Statement
You are given a string S of length N consisting of 0 and 1. It describes a length-N sequence A =
(A1 , A2 , … , AN ). If the i-th character of S (1 ≤ i ≤ N ) is 0, then Ai = 0; if it is 1, then Ai = 1.
​ ​ ​ ​ ​

Find the following:

∑ (⋯ ((Ai ⊼ Ai+1 ) ⊼ Ai+2 ) ⊼ ⋯ ⊼ Aj )


​ ​ ​ ​ ​

1≤i≤j≤N

N N
More formally, find ∑ ∑ f (i, j) for f (i, j) (1
​ ​ ≤ i ≤ j ≤ N ) defined as follows:
i=1 j=i

(i = j)
f (i, j) = {
Ai ​

f (i, j − 1) ⊼ Aj (i < j)
​ ​

Here, ⊼, NAND, is a binary operator satisfying the following:

0 ⊼ 0 = 1, 0 ⊼ 1 = 1, 1 ⊼ 0 = 1, 1 ⊼ 1 = 0.

Constraints
1 ≤ N ≤ 106
S is a string of length N consisting of 0 and 1.
All input values are integers.

Input
The input is given from Standard Input in the following format:

N
S

Output
Print the answer in a single line.
Sample Input 1
5
00110

Sample Output 1
9

Here are the values of f (i, j) for the pairs (i, j) such that 1 ≤ i ≤ j ≤ N:
f (1, 1) = 0 = 0
f (1, 2) = 0 ⊼ 0 = 1
f (1, 3) = (0 ⊼ 0) ⊼ 1 = 0
f (1, 4) = ((0 ⊼ 0) ⊼ 1) ⊼ 1 = 1
f (1, 5) = (((0 ⊼ 0) ⊼ 1) ⊼ 1) ⊼ 0 = 1
f (2, 2) = 0 = 0
f (2, 3) = 0 ⊼ 1 = 1
f (2, 4) = (0 ⊼ 1) ⊼ 1 = 0
f (2, 5) = ((0 ⊼ 1) ⊼ 1) ⊼ 0 = 1
f (3, 3) = 1 = 1
f (3, 4) = 1 ⊼ 1 = 0
f (3, 5) = (1 ⊼ 1) ⊼ 0 = 1
f (4, 4) = 1 = 1
f (4, 5) = 1 ⊼ 0 = 1
f (5, 5) = 0 = 0
Their sum is 0 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 1 + 0 = 9, so print 9.
Note that ⊼ does not satisfy the associative property. For instance, (1 ⊼ 1) ⊼ 0 =0⊼0=1=
0=
1 ⊼ 1 = 1 ⊼ (1 ⊼ 0).

Sample Input 2
30
101010000100101011010011000010

Sample Output 2
326
F - Make 10 Again
Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 500 points

Problem Statement
We have N dice. For each i = 1, 2, … , N , when the i-th die is thrown, it shows a random integer
between 1 and Ai , inclusive, with equal probability.

Find the probability, modulo 998244353, that the following condition is satisfied when the N dice are
thrown simultaneously.

There is a way to choose some (possibly all) of the N dice so that the sum of their results is 10.

How to find a probability modulo 998244353

Constraints
1 ≤ N ≤ 100
1 ≤ Ai ≤ 106

All input values are integers.

Input
The input is given from Standard Input in the following format:

N
A1 A2 … AN
​ ​ ​

Output
Print the answer.

Sample Input 1
4
1 7 2 9
Sample Output 1
942786334

For instance, if the first, second, third, and fourth dice show 1, 3, 2, and 7, respectively, these results
satisfy the condition. In fact, if the second and fourth dice are chosen, the sum of their results is 3 + 7 =
10. Alternatively, if the first, third, and fourth dice are chosen, the sum of their results is 1 + 2 + 7 = 10.
On the other hand, if the first, second, third, and fourth dice show 1, 6, 1, and 5, respectively, there is no
way to choose some of them so that the sum of their results is 10, so the condition is not satisfied.
11
In this sample input, the probability of the results of the N dice satisfying the condition is 18 . Thus, print

this value modulo 998244353, that is, 942786334.

Sample Input 2
7
1 10 100 1000 10000 100000 1000000

Sample Output 2
996117877
G - Takahashi And Pass-The-Ball Game

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 550 points

Problem Statement
There are N Takahashi.

The i-th Takahashi has an integer Ai and Bi balls.


​ ​

An integer x between 1 and K , inclusive, will be chosen uniformly at random, and they will repeat the
following operation x times.

For every i, the i-th Takahashi gives all his balls to the Ai -th Takahashi.

Beware that all N Takahashi simultaneously perform this operation.

For each i = 1, 2, … , N , find the expected value, modulo 998244353, of the number of balls the i-th
Takahashi has at the end of the operations.

How to find a expected value modulo 998244353

Constraints
1 ≤ N ≤ 2 × 105
1 ≤ K ≤ 1018
K is not a multiple of 998244353.
1 ≤ Ai ≤ N  (1 ≤ i ≤ N )

0 ≤ Bi < 998244353 (1 ≤ i ≤ N )

All input values are integers.

Input
The input is given from Standard Input in the following format:

N K
A1 A2 ⋯ AN
​ ​ ​

B1 B2 ⋯ BN
​ ​ ​

Output
Print the expected value of the number of balls the i-th Takahashi has at the end of the operations for
i = 1, 2, … , N , separated by spaces, in a single line.
Sample Input 1
5 2
3 1 4 1 5
1 1 2 3 5

Sample Output 1
3 0 499122179 499122178 5

During two operations, the five Takahashi have the following number of balls.

If x = 1 is chosen, the five Takahashi have 4, 0, 1, 2, 5 balls.


If x = 2 is chosen, the five Takahashi have 2, 0, 4, 1, 5 balls.
5 3
Thus, the sought expected values are 3, 0, , , 5. Print these values modulo 998244353, that is,
2 2
​ ​

3, 0, 499122179, 499122178, 5, separated by spaces.


Sample Input 2
3 1000
1 1 1
1 10 100

Sample Output 2
111 0 0

After one or more operations, the first Takahashi gets all balls.

Sample Input 3
16 1000007
16 12 6 12 1 8 14 14 5 7 6 5 9 6 10 9
719092922 77021920 539975779 254719514 967592487 476893866 368936979 465399362 342544824 540338192
42663741 165480608 616996494 16552706 590788849 221462860

Sample Output 3
817852305 0 0 0 711863206 253280203 896552049 935714838 409506220 592088114 0 413190742 0 363914270
0 14254803

Sample Input 4
24 100000000007
19 10 19 15 1 20 13 15 8 23 22 16 19 22 2 20 12 19 17 20 16 8 23 6
944071276 364842194 5376942 671161415 477159272 339665353 176192797 2729865 676292280 249875565 259
803120 103398285 466932147 775082441 720192643 535473742 263795756 898670859 476980306 12045411 620
291602 593937486 761132791 746546443

Sample Output 4
918566373 436241503 0 0 0 455245534 0 356196743 0 906000633 0 268983266 21918337 0 733763572 173816
039 754920403 0 273067118 205350062 0 566217111 80141532 0
Ex - Negative Cost

Time Limit: 3 sec / Memory Limit: 1024 MB

Score : 625 points

Problem Statement
A monster with health H has appeared right in front of you. Your magic power is now 0.

You can use N moves called move 1, move 2, …, move N , any number of times in any order.

For each i= 1, 2, … , N , move i can only be used when your magic power is at least Ci , and its use will

decrease your magic power by Ci and the monster's health by Di . Here, if Ci is negative, decreasing your
​ ​ ​

magic power by Ci means increasing it by −Ci .


​ ​

Find the minimum possible number of times you use moves before the monster's health is 0 or lower. The
constraints of this problem guarantee that a finite number of uses of moves can make it 0 or lower (see
below).

Constraints
1 ≤ N ≤ 300
1 ≤ H ≤ 1018
−300 ≤ Ci ≤ 300 ​

Ci ≤ 0 for some 1 ≤ i ≤ N .

1 ≤ Di ≤ 109 ​

All input values are integers.

Input
The input is given from Standard Input in the following format:

N H
C1 D1
​ ​

C2 D2
​ ​


CN DN ​ ​

Output
Print the answer.
Sample Input 1
3 48
3 20
-4 2
1 5

Sample Output 1
5

From the initial state where your magic power is 0 and the monster's health is 48, consider using moves as
follows.

Use move 2. Now, your magic power is 4, and the monster's health is 46.
Use move 3. Now, your magic power is 3, and the monster's health is 41.
Use move 1. Now, your magic power is 0, and the monster's health is 21.
Use move 2. Now, your magic power is 4, and the monster's health is 19.
Use move 1. Now, your magic power is 1, and the monster's health is −1.

Here, you use moves five times before the monster's health is not greater than 0, which is the minimum
possible number.

Sample Input 2
20 583988303060450752
-64 273760634
-238 960719353
-114 191410838
-250 357733867
232 304621362
-286 644706927
210 37849132
-230 556412112
-142 136397527
101 380675202
-140 152300688
190 442931589
-187 940659077
-12 312523039
32 126515475
-143 979861204
105 488280613
240 664922712
290 732741849
69 541282303
Sample Output 2
595990842
HINTS, ALGORITHMS AND
SAMPLE
IMPLEMENTATIONS FOR
EACH PROBLEM
STATEMENTS
A – ORDER SOMETHING ELSE

Algorithm:

Step 1: Read input values

1.1. Read the integer `n` - the number of dishes available.

1.2. Read the integer `p` - the price when the coupon is not used.

1.3. Read the integer `q` - the price when the coupon is used and the cheapest dish is ordered.

Step 2: Ini!alize variables

2.1. Ini!alize the variable `d_min` to a large value, e.g., 1000000000, to ensure that the first dish's
price will be smaller than `d_min`.

2.2. Ini!alize a temporary variable `d` to store the price of each dish while inspec!ng them.

Step 3: Find the price of the cheapest dish

3.1. Start a loop from `i = 1` to `n` (inclusive) using a for loop, to inspect each dish one by one.

3.2. Within the loop, read the price of the current dish and store it in the variable `d`.

3.3. Update the value of `d_min` to be the minimum between the current `d` and the current value of
`d_min`. This will help keep track of the cheapest dish price encountered so far.

Step 4: Compute and print the result

4.1. A4er the loop, compute the minimum price between `p` and `q + d_min`.

4.2. Print the result obtained in step 4.1.

Step 5: End of the algorithm

5.1. Exit the program.


The final C++ code using the algorithm above:

#include <iostream>

using namespace std;

int main(void)

int n, p, q;

cin >> n >> p >> q;

int d_min = 1000000000, d;

for (int i = 1; i <= n; i++)

cin >> d;

d_min = min(d, d_min);

cout << min(p, q + d_min) << endl;

return 0;

This algorithm will help you find and print the cheapest price between ordering without a coupon (`p`)
and ordering with a coupon for the cheapest dish (`q + d_min`).
B – STRICTLY SUPERIOR

Algorithm:

Step 1: Read input values

1.1. Read the integers `N` and `M` from the input - `N` represents the number of products, and `M`
represents the number of features each product can have.

Step 2: Read product informa!on

2.1. Create a vector of pairs called `products`, where each pair consists of an integer `price` and a
vector of integers `feature`.

2.2. Iterate `N` !mes to read the product informa!on for each product.

2.3. For each product, read the `price` first.

2.4. Read the integer `K` - the number of features for the current product.

2.5. Create a vector of integers called `feature` with size `K`.

2.6. Read `K` integers and store them in the `feature` vector to represent the features of the current
product.

Step 3: Define `is_strictly_superior` func!on

3.1. Create a func!on called `is_strictly_superior`, which takes two pairs of `int` and `vector<int>` as
input parameters represen!ng two products - `product_i` and `product_j`.

3.2. Extract `price_i` and `feature_i` from `product_i`, and `price_j` and `feature_j` from `product_j`.

3.3. Check if the price of `product_i` is greater than or equal to the price of `product_j`.

3.4. Use the `std::includes` func!on to check if all the features of `product_i` are contained in the
features of `product_j`.

3.5. Also, check if the price of `product_i` is strictly greater than the price of `product_j`, or if the prices
are the same but the features of `product_j` are not contained in the features of `product_i`.

Step 4: Define `has_superior_pair` func!on

4.1. Create a func!on called `has_superior_pair`, which takes the `products` vector as an input
parameter.

4.2. Iterate through each product in the `products` vector using `any_of` func!on to check if there
exists any product (`product_i`) that has a superior pair.

4.3. For each `product_i`, again use `any_of` func!on to check if there exists any product (`product_j`)
in the `products` vector such that `product_j` is strictly superior to `product_i` using the
`is_strictly_superior` func!on.
Step 5: Check if a superior pair exists

5.1. Call the `has_superior_pair` func!on with the `products` vector as an argument.

5.2. If the func!on returns `true`, output "Yes"; otherwise, output "No".

Step 6: End of the algorithm

6.1. Exit the program.

The final C++ code using the algorithm above:

#include <iostream>

#include <vector>

#include <u!lity>

#include <algorithm>

using namespace std;

bool is_strictly_superior(const pair<int, vector<int>>& product_i, const pair<int, vector<int>>&


product_j) {

const auto& [price_i, feature_i] = product_i;

const auto& [price_j, feature_j] = product_j;

return price_i >= price_j &&

includes(feature_j.begin(), feature_j.end(), feature_i.begin(), feature_i.end()) &&

(price_i > price_j || !includes(feature_i.begin(), feature_i.end(), feature_j.begin(),


feature_j.end()));

bool has_superior_pair(const vector<pair<int, vector<int>>>& products) {

return any_of(products.begin(), products.end(), [&products](const auto& product_i) {

return any_of(products.begin(), products.end(), [&product_i](const auto& product_j) {

return is_strictly_superior(product_i, product_j);

});

});

}
int main() {

int N, M;

cin >> N >> M;

vector<pair<int, vector<int>>> products(N);

for (auto& [price, feature] : products) {

cin >> price;

int K;

cin >> K;

feature = vector<int>(K);

for (auto& f : feature)

cin >> f;

cout << (has_superior_pair(products) ? "Yes" : "No") << endl;

return 0;

```

This algorithm will determine if there exists a pair of products in the given list such that one product is
strictly superior to the other, based on their prices and features.
C-Reversible

Algorithm:

Sure! Here's a step-by-step algorithm for the provided C++ code:

Step 1: Read input value

1.1. Read the integer `n` from the input, represen!ng the number of s!cks.

Step 2: Ini!alize variables

2.1. Create a variable `ans` and set it to 0. This variable will keep track of the number of dis!nct s!cks
encountered so far.

2.2. Create an empty `set<string>` called `T`. This set will store the strings of the s!cks inspected so far,
along with their reversals.

Step 3: Inspect s!cks

3.1. Start a loop from `i = 1` to `n` (inclusive) using a for loop, to inspect each s!ck one by one.

3.2. Within the loop, read the string of the current s!ck and store it in the variable `s`.

3.3. Check if the string `s` is not present in the set `T` by using the `count()` func!on. If it is not present,
increment the value of `ans` by 1, as it indicates that this s!ck is a dis!nct one.

3.4. Insert the string `s` into the set `T` using `insert()` to keep track of it.

3.5. Reverse the string `s`.

3.6. Check if the reversed string of `s` is not present in the set `T`. If it is not present, increment the
value of `ans` by 1, as the reversed string is also dis!nct.

3.7. Insert the reversed string of `s` into the set `T` to keep track of it.

Step 4: Print the result

4.1. A4er the loop, print the value of `ans`, which represents the number of dis!nct s!cks encountered.

Step 5: End of the algorithm

5.1. Exit the program.

The final C++ code using the algorithm above:


#include <iostream>

#include <set>

#include <algorithm>

using namespace std;

int main(void)

int n;

cin >> n;

int ans = 0;

set<string> T;

string s;

for (int i = 1; i <= n; i++)

cin >> s;

if (T.count(s) == 0)

ans++;

T.insert(s);

reverse(s.begin(), s.end());

T.insert(s);

cout << ans << endl;

return 0;

This algorithm will efficiently count the number of dis!nct s!cks by using a balanced binary tree
(implemented as a `std::set`) to keep track of the strings of the s!cks and their reversals inspected so
far. The algorithm ensures that it finishes within the execu!on !me limit by using the set's fast lookup
opera!on.
D – Peaceful Teams:

Algorithm:

The problem can be solved by adding players to a team one by one with certain constraints on player
incompa!bility. The main idea is to use a recursive func!on to explore all possible combina!ons of
dividing players into teams while ensuring that no incompa!ble players belong to the same team.

Here's the step-by-step algorithm for the given code:

Step 1: Read input values

1.1. Read the integers `N`, `T`, and `M` from the input.

- `N` represents the number of players.

- `T` represents the desired number of teams.

- `M` represents the number of pairs of players who are incompa!ble with each other.

Step 2: Read incompa!bility data

2.1. Create a vector called `hate` of size `N`, where each element is an unsigned integer.

2.2. Iterate `M` !mes to read the incompa!bility pairs and store them in the `hate` vector.

- Each pair consists of integers `a` and `b`, where `a` and `b` are player indices (0-indexed) who are
incompa!ble with each other.

- Set the corresponding bits in the `hate` vector to indicate player incompa!bility.

Step 3: Define a recursive func!on `dfs`

3.1. Create a lambda func!on called `dfs`, which takes the following parameters:

- `auto&& f`: A reference to itself for recursion.

- `vector<unsigned>& teams`: A reference to the vector that holds the teams' bitmasks.

- `unsigned now`: The index of the player currently being considered.

3.2. The `dfs` func!on returns the number of valid combina!ons to divide players into teams.

Step 4: Implement the recursive func!on `dfs`

4.1. The `dfs` func!on performs the following steps recursively:

- If all `N` players are considered (`now == N`), check if the number of teams formed is equal to the
desired number of teams `T`. If yes, return 1; otherwise, return 0.
- If the current player `now` can be added to an exis!ng team without causing any incompa!bility
issues, try adding the player to each exis!ng team. Recursively call `dfs` for the next player (`now + 1`),
considering all possible combina!ons.

- If there are fewer teams formed than the desired number of teams `T`, try crea!ng a new team
with the current player. Recursively call `dfs` for the next player (`now + 1`), considering all possible
combina!ons.

Step 5: Call the recursive func!on and print the result

5.1. Call the `dfs` func!on with an ini!al empty vector for teams and the star!ng player index `0`.

5.2. Print the result obtained from the `dfs` func!on, which represents the number of valid
combina!ons to divide players into teams without any incompa!ble players in the same team.

Step 6: End of the algorithm

6.1. Exit the program.

The final C++ code using the algorithm above:

```cpp

#include <iostream>

#include <vector>

int main() {

using namespace std;

unsigned N, T, M;

cin >> N >> T >> M;

// j-th bit of hate[i] is 1 ⟹ i-th and j-th players are incompa!ble (0-indexed)

vector<unsigned> hate(N);

for(unsigned i{}, a, b; i < M; ++i){

cin >> a >> b;

hate[--b] |= 1U << --a;

}
// Define the recursive func!on dfs

auto dfs{[N, T, &hate](auto&& f, vector<unsigned>& teams, unsigned now) -> unsigned {

// OK if there are T teams so far when all the N players are inspected

if(now == N)

return size(teams) == T;

unsigned ans{};

// Add the now-th player to an exis!ng team

for(auto&& team : teams)

// If nobody in the team is incompa!ble with the now-th player

if(!(team & hate[now])){

team ^= 1U << now;

ans += f(f, teams, now + 1);

team ^= 1U << now;

// If a new team can be made, make a new one

if(size(teams) < T){

teams.emplace_back(1U << now);

ans += f(f, teams, now + 1);

teams.pop_back();

return ans;

}};

// Print the result of the recursive func!on

cout << [dfs{[N, T, &hate](auto&& f, vector<unsigned>& teams, unsigned now) -> unsigned {

if(now == N)

return size(teams) == T;
unsigned ans{};

for(auto&& team : teams)

if(!(team & hate[now])){

team ^= 1U << now;

ans += f(f, teams, now + 1);

team ^= 1U << now;

if(size(teams) < T){

teams.emplace_back(1U << now);

ans += f(f, teams, now + 1);

teams.pop_back();

return ans;

}}, T]{

vector<unsigned> team;

team.reserve(T);

return dfs(dfs, team, 0);

}() << endl;

return 0;

```

This algorithm efficiently explores all possible combina!ons of dividing players into teams while
ensuring that no incompa!ble players belong to the same team. It uses a recursive approach and
bitwise opera!ons to achieve a !me complexity of O(N * N!) with a reasonable number of players.
E – NAND repeatedly

Algorithm

We can efficiently solve the problem by managing the counts of '0' and '1' in the input string 'A'. The
algorithm has a !me complexity of Θ(N) since it only iterates through the input string once, and it does
not require any nested loops or expensive opera!ons.

Here's the step-by-step algorithm for the given solu!on:

Step 1: Read input values

1.1. Read the integer `N` from the input, represen!ng the length of the string.

1.2. Read the string `A` from the input, which consists of '0's and '1's.

Step 2: Ini!alize variables

2.1. Create two variables `zero` and `one`, both ini!alized to 0. These variables will keep track of the
counts of '0's and '1's in the processed part of the string.

2.2. Create a variable `ans` and set it to 0. This variable will keep track of the total sum of '1's
encountered so far.

Step 3: Iterate through the string

3.1. Iterate through each character `a` in the string `A`.

3.2. Inside the loop, update the counts of '0's and '1's based on the current character `a`.

- If `a` is '0', update `zero` to 1 and `one` to the sum of their previous values (`zero + one`).

- If `a` is '1', update `zero` to the sum of their previous values (`zero + one`) and `one` to the sum of
their previous values plus 1 (`zero + one + 1`).

3.3. Add the value of `one` to the `ans` variable to keep track of the total sum of '1's.

Step 4: Print the result

4.1. A4er the loop, print the value of `ans`, which represents the sum of '1's obtained by processing
the string `A`.

Step 5: End of the algorithm

5.1. Exit the program.


The final Python and C++ codes using the algorithm above:

Python:

N = int(input())

A = input()

zero, one = 0, 0

ans = 0

for a in A:

if a == '0':

zero, one = 1, zero + one

else:

zero, one = one, zero + 1

ans += one

print(ans)

C++:

#include <vector>

#include <iostream>

#include <u!lity>

int main() {

using namespace std;

unsigned long N;

cin >> N;

vector<char> A(N);

for (auto &&a : A) cin >> a;

unsigned long ans = 0;


using count_t = pair<unsigned long, unsigned long>;

count_t counter;

auto&& [zero, one] = counter;

for (const auto a : A) {

counter = a == '1' ? count_t{one, zero + 1} : count_t{1, one + zero};

ans += one;

cout << ans << endl;

return 0;

Both the Python and C++ implementa!ons efficiently solve the problem and produce the correct
output in linear !me, making the algorithm much more efficient than the ini!al Θ(N^2)-!me solu!on.
G - Takahashi And Pass-The-Ball Game

HINTS:
Algorithm:

With this we can efficiently solves the "Takahashi And Pass-The-Ball Game" problem using the doubling
technique and modular arithme!c. The problem requires finding the number of balls each player will
have a4er performing the pass-the-ball opera!on K !mes.

Here's the step-by-step algorithm for the given solu!on:

Step 1: Read input values

1.1. Read the integers `N` and `K` from the input.

- `N` represents the number of players.

- `K` represents the number of !mes the pass-the-ball opera!on is performed.

Step 2: Precompute K_inv (K inverse modulo 998244353)

2.1. Compute `K_inv` using the `atcoder::sta!c_modint` library provided by AtCoder. This step is
necessary for dividing the answer by K later.

Step 3: Read player informa!on

3.1. Create a vector called `A` of size `N`, which will store the target player to whom each player will
pass the ball.

3.2. Create a vector called `ball` of size `N`, which will store the number of balls each player currently
has.

Step 4: Perform the pass-the-ball opera!on once


4.1. Use the `apply` func!on to perform the pass-the-ball opera!on once based on the player
informa!on in vector `A`.

Step 5: Implement doubling technique

5.1. Use the `while` loop to perform the doubling technique to compute the final result efficiently.

5.2. Within the loop, if K is odd, consider the first opera!on and the remaining opera!ons separately.

5.3. Put the two opera!ons together using the `add` func!on and apply the current opera!on to the
`ball` vector.

5.4. Update the `A` vector using the `compose` func!on to represent the composi!on of opera!ons i
→ B[i] → A[B[i]].

Step 6: Divide by K and print the result

6.1. A4er the loop, mul!ply the result vector `ans` by `K_inv` to find the answer.

6.2. Print each element of the `ans` vector separated by spaces to represent the number of balls each
player has a4er K opera!ons.

Step 7: End of the algorithm

7.1. Exit the program.

The final C++ code using the algorithm above:

#include <bits/extc++.h>

#include <atcoder/modint>

template<int m>

std::ostream& operator<<(std::ostream& os, const atcoder::sta!c_modint<m>& mint) {

os << mint.val();

return os;

int main() {

using namespace std;


using modint = atcoder::sta!c_modint<998244353>;

unsigned long N, K;

cin >> N >> K;

const auto K_inv{modint{K}.inv()};

vector<unsigned long> A(N);

for (auto&& a : A) {

cin >> a;

--a;

vector<modint> ball(N);

for (auto&& b : ball) {

int x;

cin >> x;

b = modint::raw(x);

// Composi!on of opera!ons i → B[i] → A[B[i]]

const auto compose{[N](auto&& A, const auto& B) {

vector<unsigned long> result(N);

for (unsigned long i{}; i < N; ++i) result[i] = A[B[i]];

A = result;

}};

// Move the balls

const auto apply{[N](const auto& A, const auto& x) {

vector<modint> result(N);

for (unsigned long i{}; i < N; ++i) result[A[i]] += x[i];

return result;
}};

const auto add{[N](auto&& x, const auto& y) {

for (unsigned long i{}; i < N; ++i) x[i] += y[i];

}};

ball = apply(A, ball); // Perform the opera!on once

vector<modint> ans(N);

while (K) {

if (K & 1) { // If K is odd, consider the first and the remaining

add(ans, ball);

ball = apply(A, ball);

// Put the two together

add(ball, apply(A, ball));

compose(A, A);

K /= 2;

// Mul!ply by 1/K to find the answer

for (const auto& x : ans) cout << x * K_inv << " ";

cout << endl;

return 0;

This algorithm efficiently solves the problem using the doubling technique and modular arithme!c,
making it suitable for large values of N and K. The !me complexity is O(NlogK + logmod), where mod
is the modular value (998244353 in this case).
Note & Credits: Problem statement and Hints from Atcoder.jp by an user en_translator

Thank you.
A DETAILED EDITORIAL FOR
ATCODER - TOYOTA PROGRAMMING CONTEST 2023
(ATCODER BEGINNER CONTEST 311)

Date of Contest: 22-07-2023

Editorial by
Dr. Dinesh Kumar Anguraj, Asso. Prof., Dept. of CSE.
Website Link: https://atcoder.jp/

Contest URL: https://atcoder.jp/contests/abc310

Mode: Rated & Unrated

Number of Contest Tasks: 7 Tasks

Number of Extra Tasks: 1 Task

Note & Credits: Problem statement and Hints from Atcoder.jp by the users
“en_translator (English) & physics (Japanese)”
CONTEST PROBLEM
STATEMENTS, HINTS AND
ALGORITHMS WITH CODE
A - First ABC  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 100 points

Problem Statement
You are given a string S  consisting of A, B, and C. S  is guaranteed to contain all of A, B, and C.

If the characters of S  are checked one by one from the left, how many characters will have been checked when the following condition is satisfied for
the first time?

All of A, B, and C have appeared at least once.

Constraints
3 ≤ N ≤ 100
S  is a string of length N  consisting of A, B, and C.
S  contains all of A, B, and C.

Input
The input is given from Standard Input in the following format:

N
S

Output
Print the answer.

Sample Input 1  Copy

Copy
5
ACABB

Sample Output 1  Copy

Copy
4

In the first four characters from the left, A, B, and C appear twice, once, and once, respectively, satisfying the condition.
The condition is not satisfied by checking three or fewer characters, so the answer is 4.

Sample Input 2  Copy

Copy
4
CABC

Sample Output 2  Copy

Copy
3

In the first three characters from the left, each of A, B, and C appears once, satisfying the condition.

Sample Input 3  Copy

Copy
30
AABABBBABABBABABCABACAABCBACCA
Sample Output 3  Copy

Copy
17
A. First ABC

Algorithm:

Step 1: Input an integer 'N', which represents the length of the string 'S'.

Step 2: Input a string 'S'.

Step 3: Ini alize three boolean variables, 'exist_a', 'exist_b', and 'exist_c', to False. These
variables will be used to track if characters 'A', 'B', and 'C' have appeared in the string 'S'.

Step 4: Start a loop that iterates over the characters in the string 'S' using the index 'i' from 0
to N-1.

Step 5: Check if the current character 'S[i]' is 'A'. If it is, set the boolean variable 'exist_a' to
True, indica ng that 'A' has been found in the string.

Step 6: Check if the current character 'S[i]' is 'B'. If it is, set the boolean variable 'exist_b' to
True, indica ng that 'B' has been found in the string.

Step 7: Check if the current character 'S[i]' is 'C'. If it is, set the boolean variable 'exist_c' to
True, indica ng that 'C' has been found in the string.

Step 8: Check if all three characters 'A', 'B', and 'C' have been found in the string. If 'exist_a',
'exist_b', and 'exist_c' are all True, it means that all three characters have appeared.

Step 9: If all three characters have appeared, print the posi on (index + 1) of the first
occurrence where they appear consecu vely (i.e., the posi on 'i + 1').

Step 10: Break out of the loop since the first occurrence of 'A', 'B', and 'C' appearing
consecu vely has been found.

Step 11: The program terminates a9er the first occurrence is printed, or it finishes itera ng
through the en re string 'S' without finding the desired pa:ern.

Code:

N = int(input())

S = input()

exist_a, exist_b, exist_c = False, False, False

for i in range(N):

if S[i] == 'A': exist_a = True

if S[i] == 'B': exist_b = True

if S[i] == 'C': exist_c = True

if exist_a and exist_b and exist_c:

print(i + 1)

break
B - Vacation Together  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 200 points

Problem Statement
There are N  people numbered 1 to N .
You are given their schedule for the following D  days. The schedule for person i is represented by a string Si  of length D . If the j -th character of Si  is o,
​ ​

person i is free on the j -th day; if it is x, they are occupied that day.

From these D  days, consider choosing some consecutive days when all the people are free.
How many days can be chosen at most? If no day can be chosen, report 0.

Constraints
1 ≤ N ≤ 100
1 ≤ D ≤ 100
N  and D are integers.
Si  is a string of length D consisting of o and x.

Input
The input is given from Standard Input in the following format:

N D
S1​

S2​


SN ​

Output
Print the maximum number of days that can be chosen, or 0 if no day can be chosen.

Sample Input 1  Copy

Copy
3 5
xooox
oooxx
oooxo

Sample Output 1  Copy

Copy
2

All the people are free on the second and third days, so we can choose them.
Choosing these two days will maximize the number of days among all possible choices.

Sample Input 2  Copy

Copy
3 3
oxo
oxo
oxo

Sample Output 2  Copy

Copy
1
Note that the chosen days must be consecutive. (All the people are free on the first and third days, so we can choose either of them, but not both.)

Sample Input 3  Copy

Copy
3 3
oox
oxo
xoo

Sample Output 3  Copy

Copy
0

Print 0 if no day can be chosen.

Sample Input 4  Copy

Copy
1 7
ooooooo

Sample Output 4  Copy

Copy
7

Sample Input 5  Copy

Copy
5 15
oxooooooooooooo
oxooxooooooooox
oxoooooooooooox
oxxxooooooxooox
oxooooooooxooox

Sample Output 5  Copy

Copy
5
B. Vaca on Together

Algorithm:

This C++ code takes two integer inputs, 'N' and 'D', followed by an array of strings 'S' of size 'N'. The
code then finds the maximum number of consecu#ve columns in the matrix where all the elements
in each column are 'o'. Finally, it prints the maximum number of consecu#ve columns with all 'o's.
Let's go through the code step by step:

Step 1: Input integers 'N' and 'D', represen#ng the number of rows and columns in the matrix,
respec#vely.

Step 2: Input 'N' strings and store them in the vector 'S', represen#ng the matrix.

Step 3: Ini#alize variables 'ans' and 'cur' to 0. 'ans' will keep track of the maximum number of
consecu#ve columns with all 'o's, and 'cur' will keep track of the current consecu#ve columns.

Step 4: Start a loop that iterates over each column (j) from 0 to 'D-1'.

Step 5: Ini#alize the variable 'can' to 1. 'can' will be used to check if all elements in the current
column are 'o'.

Step 6: For each column 'j', loop through all the rows (i) from 0 to 'N-1'.

Step 7: Check if the element at row 'i' and column 'j' (S[i][j]) is 'o'. If it is not 'o', set 'can' to 0,
indica#ng that the current column doesn't meet the condi#on of having all 'o's.

Step 8: A9er the inner loop, if 'can' is s#ll 1, it means that all elements in the current column are 'o'.

Step 9: Increment the value of 'cur' to represent the number of consecu#ve columns with all 'o's.

Step 10: If 'can' is 0, it means that the current column does not have all 'o's, so reset 'cur' to 0.

Step 11: Update 'ans' to be the maximum value between 'ans' and 'cur', ensuring it keeps track of the
longest consecu#ve sequence of columns with all 'o's seen so far.

Step 12: Con#nue the loop for the next column.

Step 13: Print the final value of 'ans', which represents the maximum number of consecu#ve
columns with all 'o's.

Step 14: The program terminates a9er prin#ng the answer.

#include <iostream>

#include <string>

#include <vector>

using namespace std;

int main() {

int N, D;

cin >> N >> D;

vector<string> S(N);
for (auto& s : S) cin >> s;

int ans = 0, cur = 0;

for (int j = 0; j < D; j++) {

int can = 1;

for (int i = 0; i < N; i++) {

can &= S[i][j] == 'o';

if (can) {

cur++;

} else {

cur = 0;

ans = max(ans, cur);

cout << ans << "\n";

}
C - Find it!  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 350 points

Problem Statement
There is a directed graph with N  vertices and N  edges.
The i-th edge goes from vertex i to vertex Ai . (The constraints guarantee that i ​
=
 Ai .)

Find a directed cycle without the same vertex appearing multiple times.
It can be shown that a solution exists under the constraints of this problem.

Notes
The sequence of vertices B = (B1 , B2 , … , BM ) is called a directed cycle when all of the following conditions are satisfied:
​ ​ ​

M ≥2
The edge from vertex Bi  to vertex Bi+1  exists. (1 ​ ​ ≤ i ≤ M − 1)
The edge from vertex BM  to vertex B1  exists. ​ ​

If i =
 j , then Bi 
= Bj . ​ ​

Constraints
All input values are integers.
2 ≤ N ≤ 2 × 105
1 ≤ Ai ≤ N ​

Ai 
=i

Input
The input is given from Standard Input in the following format:

N
A1 A2 … AN
​ ​ ​

Output
Print a solution in the following format:

M
B1 B2 … BM
​ ​ ​

M  is the number of vertices, and Bi  is the i-th vertex in the directed cycle. ​

The following conditions must be satisfied:

2≤M
Bi+1 = ABi  ( 1 ≤ i ≤ M − 1 )


B1 = AB M


Bi 
= Bj  ( i =

 j  ) ​

If multiple solutions exist, any of them will be accepted.

Sample Input 1  Copy

Copy
7
6 7 2 1 3 4 5

Sample Output 1  Copy

Copy
4
7 5 3 2

7 → 5 → 3 → 2 → 7 is indeed a directed cycle.


Here is the graph corresponding to this input:
Here are other acceptable outputs:

4
2 7 5 3

3
4 1 6

Note that the graph may not be connected.

Sample Input 2  Copy

Copy
2
2 1

Sample Output 2  Copy

Copy
2
1 2

This case contains both of the edges 1 → 2 and 2 → 1.


In this case, 1 → 2 → 1 is indeed a directed cycle.
Here is the graph corresponding to this input, where 1 ↔ 2 represents the existence of both 1 → 2 and 2 → 1:

Sample Input 3  Copy

Copy
8
3 7 4 7 3 3 8 2

Sample Output 3  Copy

Copy
3
2 7 8

Here is the graph corresponding to this input:


C. Find It

Algorithm:

This C++ code takes an integer 'n' as input, followed by an array 'a' of size 'n'. The code finds and prints
a cycle in a given directed graph represented by the array 'a'. The graph is assumed to have nodes
numbered from 1 to n, and the values in the array 'a' represent the next node in the directed graph.

Step 1: Input the integer 'n', which represents the number of nodes in the directed graph.

Step 2: Create a vector 'a' of size 'n+1' to store the directed graph's edges. The index represents the
node number, and the value at index i represents the next node in the directed graph from node i.

Step 3: Input the values of the array 'a'.

Step 4: Create a vector 'fl' of size 'n+1' and ini)alize all its elements to 0. This vector will be used to
mark visited nodes during the cycle-finding process.

Step 5: Create an empty vector 's' to store the nodes visited in the current traversal.

Step 6: Ini)alize 'v' to 1. This variable represents the current node being explored, and we can start
from any vertex (here, we start from vertex 1).

Step 7: While the node 'v' is not visited (fl[v] is 0), do the following:

Mark the current node 'v' as visited by se5ng 'fl[v]' to 1.

Add the current node 'v' to the vector 's' to keep track of the traversal path.

Update 'v' to be the next node in the directed graph, i.e., 'v = a[v]'.

Step 8: A:er the above loop, we have either encountered a cycle or reached the end of a connected
component.

Step 9: Create an empty vector 'res' to store the nodes that belong to the cycle.

Step 10: Traverse through the vector 's' and add the nodes to 'res' un)l we reach the node 'v' again.
This means that we have detected a cycle, and we add all the nodes from 's' that belong to the cycle
to 'res'.

Step 11: Print the size of the cycle (number of nodes) followed by the nodes that form the cycle.

Step 12: The program terminates a:er prin)ng the cycle informa)on.

The code essen)ally performs a depth-first search (DFS) on the directed graph, keeping track of the
nodes visited to detect cycles efficiently.

Code:

#include<bits/stdc++.h>

using namespace std;

int main(){

int n;

cin >> n;
vector<int> a(n+1);

for(int i=1;i<=n;i++){

cin >> a[i];

vector<int> fl(n+1,0),s;

int v=1; // any vertex is ok to start

while(fl[v]==0){

fl[v]=1;

s.push_back(v);

v=a[v];

vector<int> res;

for(auto &nx : s){

if(nx==v){v=-1;}

if(v==-1){res.push_back(nx);}

cout << res.size() << "\n";

for(int i=0;i<res.size();i++){

if(i){cout << " ";}

cout << res[i];

}cout << "\n";

return 0;

}
D - Grid Ice Floor  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 400 points

Problem Statement
There is an N × M  grid and a player standing on it.
Let (i, j) denote the square at the i-th row from the top and j -th column from the left of this grid.
Each square of this grid is ice or rock, which is represented by N  strings S1 , S2 , … , SN  of length M  as follows:
​ ​ ​

if the j -th character of Si  is ., square (i, j) is ice;


if the j -th character of Si  is #, square (i, j) is rock.


The outer periphery of this grid (all squares in the 1-st row, N -th row, 1-st column, M -th column) is rock.

Initially, the player rests on the square (2, 2), which is ice.


The player can make the following move zero or more times.

First, specify the direction of movement: up, down, left, or right.


Then, keep moving in that direction until the player bumps against a rock. Formally, keep doing the following:
if the next square in the direction of movement is ice, go to that square and keep moving;
if the next square in the direction of movement is rock, stay in the current square and stop moving.

Find the number of ice squares the player can touch (pass or rest on).

Constraints
3 ≤ N , M ≤ 200
Si  is a string of length M  consisting of # and ..

Square (i, j) is rock if i = 1, i = N , j = 1, or j = M .


Square (2, 2) is ice.

Input
The input is given from Standard Input in the following format:

N M
S1 ​

S2 ​


SN ​

Output
Print the answer as an integer.

Sample Input 1  Copy

Copy
6 6
######
#....#
#.#..#
#..#.#
#....#
######

Sample Output 1  Copy

Copy
12

For instance, the player can rest on (5, 5) by moving as follows:

(2, 2) → (5, 2) → (5, 5).


The player can pass (2, 4) by moving as follows:
(2, 2) → (2, 5), passing (2, 4) in the process.
The player cannot pass or rest on (3, 4).

Sample Input 2  Copy

Copy
21 25
#########################
#..............###...####
#..............#..#...###
#........###...#...#...##
#........#..#..#........#
#...##...#..#..#...#....#
#..#..#..###...#..#.....#
#..#..#..#..#..###......#
#..####..#..#...........#
#..#..#..###............#
#..#..#.................#
#........##.............#
#.......#..#............#
#..........#....#.......#
#........###...##....#..#
#..........#..#.#...##..#
#.......#..#....#..#.#..#
##.......##.....#....#..#
###.............#....#..#
####.................#..#
#########################

Sample Output 2  Copy

Copy
215
D- Grid Ice Floor

Algorithm:

This C++ code is an implementa on of a breadth-first search (BFS) algorithm to find the number of
cells reachable in a grid-based game. The game grid is represented by a 2D matrix, and the player can
move in four direc ons (up, down, le', right) un l it hits a rock (represented by the character '#'). The
player can also choose to stop moving (represented by the character '*'). The goal is to find the
maximum number of reachable cells a'er following these rules. Here's a step-by-step explana on of
the code:

Step 1: Input integers 'n' and 'm', represen ng the number of rows and columns in the grid.

Step 2: Input the 'n' rows of the grid represented by strings and store them in the vector 's'.

Step 3: Ini alize a vector 'fl' of size '5 * n * m' (5 mes the total number of cells) and set all its elements
to 0. This vector will be used to mark visited cells during the BFS traversal.

Step 4: Create a queue 'q' to store cell posi ons during BFS traversal.

Step 5: Ini alize the star ng cell posi on as (x, y) = (m+1, 4) and direc on 'd' = 4 (stop). The star ng
cell is chosen arbitrarily to start the BFS.

Step 6: Mark the star ng cell as visited (fl[5 * (m + 1) + 4] = 1) and add it to the queue.

Step 7: Start the BFS loop, which runs while the queue is not empty.

Step 8: Pop a cell posi on 'od' from the front of the queue.

Step 9: Convert the cell posi on 'od' to x, y, and d using simple arithme c opera ons.

Step 10: If the direc on 'd' is 4 (stop), try to move in all four direc ons (up, down, le', right) and check
if the next cell is empty ('.'). If it is, mark the cell as visited and add it to the queue with the new
direc on.

Step 11: If the direc on 'd' is not 4, it means the player can con nue moving in the current direc on.
Check if the next cell in the same direc on is empty ('.'). If it is, mark the cell as visited and add it to
the queue with the same direc on.

Step 12: If the next cell in the same direc on is not empty, it means the player hit a rock ('#'). In this
case, mark the current cell as visited and add it to the queue with the direc on 4 (stop).

Step 13: Con nue the BFS loop un l all reachable cells are visited.

Step 14: Count the number of reachable cells by itera ng through all the cells and taking the maximum
value among five direc ons (fl[5i], fl[5i+1], fl[5i+2], fl[5i+3], fl[5*i+4]) and adding them to 'res'.

Step 15: Print the final result 'res', which represents the maximum number of reachable cells.

Step 16: The program terminates a'er prin ng the result.

Code:

#include<bits/stdc++.h>

using namespace std;

int dx4[4]={1,-1,0,0};
int dy4[4]={0,0,1,-1};

int main(){

int n,m;

cin >> n >> m;

vector<string> s(n);

for(auto &nx : s){cin >> nx;}

vector<int> fl(5*n*m,0);

queue<int> q;

fl[5*(m+1)+4]=1;

q.push(5*(m+1)+4);

while(!q.empty()){

int od=q.front();q.pop();

int x=(od/5)/m;

int y=(od/5)%m;

int d=od%5;

if(d==4){

// stop

for(int i=0;i<4;i++){

int nx=x+dx4[i];

int ny=y+dy4[i];

int nd=i;

if(s[nx][ny]=='.'){

int nid=5*(nx*m+ny)+nd;

if(fl[nid]==0){

fl[nid]=1;

q.push(nid);

else{
// keep the direc on

int nx=x+dx4[d];

int ny=y+dy4[d];

int nd=d;

if(s[nx][ny]=='.'){

int nid=5*(nx*m+ny)+nd;

if(fl[nid]==0){

fl[nid]=1;

q.push(nid);

else{

// hit a rock

int nid=5*(x*m+y)+4;

if(fl[nid]==0){

fl[nid]=1;

q.push(nid);

int res=0;

for(int i=0;i<n*m;i++){

res+=max({fl[5*i],fl[5*i+1],fl[5*i+2],fl[5*i+3],fl[5*i+4]});

cout << res << "\n";

return 0;

}
E - Defect-free Squares  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 475 points

Problem Statement
There is a grid with H  rows and W  columns. Let (i, j) denote the square at the i-th row from the top and j -th column from the left of the grid.
Each square of the grid is holed or not. There are exactly N  holed squares: (a1 , b1 ), (a2 , b2 ), … , (aN , bN ).
​ ​ ​ ​ ​ ​

When the triple of positive integers (i, j, n) satisfies the following condition, the square region whose top-left corner is (i, j) and whose bottom-right
corner is (i + n − 1, j + n − 1) is called a holeless square.
i + n − 1 ≤ H.
j + n − 1 ≤ W.
For every pair of non-negative integers (k, l) such that 0 ≤ k ≤ n − 1, 0 ≤ l ≤ n − 1, square (i + k, j + l) is not holed.
How many holeless squares are in the grid?

Constraints
1 ≤ H, W ≤ 3000
0 ≤ N ≤ min(H × W , 105 )
1 ≤ ai ≤ H ​

1 ≤ bi ≤ W ​

All (ai , bi ) are pairwise different.


​ ​

All input values are integers.

Input
The input is given from Standard Input in the following format:

H W N
a1 b1
​ ​

a2 b2
​ ​


aN bN​ ​

Output
Print the number of holeless squares.

Sample Input 1  Copy

Copy
2 3 1
2 3

Sample Output 1  Copy

Copy
6

There are six holeless squares, listed below. For the first five, n = 1, and the top-left and bottom-right corners are the same square.
The square region whose top-left and bottom-right corners are (1, 1).
The square region whose top-left and bottom-right corners are (1, 2).
The square region whose top-left and bottom-right corners are (1, 3).
The square region whose top-left and bottom-right corners are (2, 1).
The square region whose top-left and bottom-right corners are (2, 2).
The square region whose top-left corner is (1, 1) and whose bottom-right corner is (2, 2).

Sample Input 2  Copy


Copy
3 2 6
1 1
1 2
2 1
2 2
3 1
3 2

Sample Output 2  Copy

Copy
0

There may be no holeless square.

Sample Input 3  Copy

Copy
1 1 0

Sample Output 3  Copy

Copy
1

The whole grid may be a holeless square.

Sample Input 4  Copy

Copy
3000 3000 0

Sample Output 4  Copy

Copy
9004500500
E - Defect-free Squares – Editorial

Algorithm:

The step-by-step algorithm for the dynamic programming approach


1. Read input:
- Read the dimensions of the grid, `H` (height) and `W` (width).
- Read the number of holes, `N`.
- Create a 2D array `hole` of size `(H+1) x (W+1)` and initialize all its elements to 0.
2. Mark holes:
- For `i` from 1 to `N`, do the following:
- Read the coordinates `a` and `b` of the `i-th` hole.
- Mark the cell at position `(a, b)` as a hole by setting `hole[a][b] = 1`.
3. Initialize dynamic programming array:
- Create a 2D array `dp` of size `(H+1) x (W+1)` and initialize all its elements to 0.
4. Dynamic Programming:
- For `i` from 1 to `H`, do the following:
- For `j` from 1 to `W`, do the following:
- If the cell at position `(i, j)` is a hole (i.e., `hole[i][j] == 1`), skip to the next cell.
- Otherwise, calculate the number of rectangles that can be formed using the empty cells up to the
current cell `(i, j)` as follows:
- `dp[i][j] = min(dp[i-1][j-1], dp[i][j-1], dp[i-1][j]) + 1`
- This equation represents the minimum size of the square that can be formed ending at cell `(i, j)`.
It takes the minimum value from the three adjacent cells above, to the left, and diagonally left-above the
current cell, then adds 1 to it.
- Accumulate the value of `dp[i][j]` into a variable `ans`, representing the total number of rectangles
formed so far.
5. Output:
- Print the final value of `ans`, which represents the total number of rectangles that can be formed using
the empty cells in the grid.
This dynamic programming approach efficiently calculates the number of rectangles that can be formed
using empty cells in the grid while avoiding redundant calculations through the use of the `dp` table.
Python Code:

def main():
H, W, N = map(int, input().split())
hole = [[0] * (W + 1) for _ in range(H + 1)]
dp = [[0] * (W + 1) for _ in range(H + 1)]

for _ in range(N):
a, b = map(int, input().split())
hole[a][b] = 1

ans = 0
for i in range(1, H + 1):
for j in range(1, W + 1):
if hole[i][j]:
con%nue
dp[i][j] = min(dp[i - 1][j - 1], dp[i][j - 1], dp[i - 1][j]) + 1
ans += dp[i][j]

print(ans)

if __name__ == "__main__":
main()
F - Yet Another Grid Task  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 525 points

Problem Statement
There is an N × M  grid and a player standing on it.
Let (i, j) denote the square at the i-th row from the top and j -th column from the left of this grid.
Each square of this grid is black or white, which is represented by N  strings S1 , S2 , … , SN  of length M  as follows:
​ ​ ​

if the j -th character of Si  is ., square (i, j) is white;


if the j -th character of Si  is #, square (i, j) is black.


The grid is said to be beautiful when the following condition is satisfied.

For every pair of integers (i, j) such that 1 ≤ i ≤ N , 1 ≤ j ≤ M , if square (i, j) is black, the square under (i, j) and the square to the immediate
lower right of (i, j) are also black (if they exist).
Formally, all of the following are satisfied.
If square (i, j) is black and square (i + 1, j) exists, square (i + 1, j) is also black.
If square (i, j) is black and square (i + 1, j + 1) exists, square (i + 1, j + 1) is also black.

Takahashi can paint zero or more white squares black, and he will do so to make the grid beautiful.
Find the number of different beautiful grids he can make, modulo 998244353.
Two grids are considered different when there is a square that has different colors in those two grids.

Constraints
1 ≤ N , M ≤ 2000
Si  is a string of length M  consisting of . and #.

Input
The input is given from Standard Input in the following format:

N M
S1​

S2​


SN ​

Output
Print the answer as an integer.

Sample Input 1  Copy

Copy
2 2
.#
..

Sample Output 1  Copy

Copy
3

He can make the following three different beautiful grids:

.# .# ##
.# ## ##

Sample Input 2  Copy


Copy
5 5
....#
...#.
..#..
.#.#.
#...#

Sample Output 2  Copy

Copy
92

Sample Input 3  Copy

Copy
25 25
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................

Sample Output 3  Copy

Copy
604936632

Find the count modulo 998244353.


F - Yet Another Grid Task:

Step-by-step algorithm:
1. Read input:
- Read the integers `n` and `m`, representing the number of rows and columns in the grid.
- Read the grid `s`, which is a vector of strings representing the rows of the grid.
2. Propagate the obstacles ('#'):
- Iterate through the grid `s`.
- If an obstacle is found at cell `(i, j)` in the grid, set the cells `(i+1, j)` and `(i+1, j+1)` to obstacles
as well (if within bounds).
- This step is to simulate the falling of obstacles downward, as indicated by the condition
`if(s[i][j]=='#')`.
3. Initialize the DP array:
- Create a DP array `dp` of size `m+1` and initialize all elements to 0.
- Set the last element of the DP array `dp[m]` to 1, as there's one way to reach the last column (it's
already marked as empty).
4. Dynamic Programming:
- Iterate through all columns in reverse order (from `m-1` to 0).
- Update the DP array values by adding the value of the next column (`j+1`) to the current column
(`j`).
- Ensure the DP array values are modulo `mod` after each addition.
5. Handle obstacles and out-of-bounds:
- Iterate through the columns and rows using the variable `c`, representing the difference between
the row and column indices.
- If `i=j+c` (the corresponding row and column index relationship) is out of bounds (`i<0` or `i>=n`)
or if the cell in the grid is an obstacle (`s[i][j]=='#'`), set the DP value of the next column (`j+1`) to 0.
6. Compute the result:
- Sum all the values in the DP array and store it in the variable `res`.
- Ensure `res` is modulo `mod` before outputting it as the result.
Python Code:
mod = 998244353
def main():
n, m = map(int, input().split())
s = []
for _ in range(n):
s.append(input().strip())
for i in range(n):
for j in range(m):
if s[i][j] == '#':
if i != (n-1):
s[i+1] = s[i+1][:j] + '#' + s[i+1][j+1:]
if i != (n-1) and j != (m-1):
s[i+1] = s[i+1][:j+1] + '#' + s[i+1][j+2:]
dp = [0] * (m + 1)
dp[m] = 1
for c in range(-m + 1, n):
for j in range(m - 1, -1, -1):
dp[j] = (dp[j] + dp[j+1]) % mod
for j in range(m):
i=j+c
if i < 0:
dp[j] = 0
elif i >= n or s[i][j] == '#':
dp[j+1] = 0
res = sum(dp) % mod
print(res)
if __name__ == "__main__":
main()
G - One More Grid Task  Editorial
 / 

Time Limit: 3 sec / Memory Limit: 1024 MB

Score : 575 points

Problem Statement
There is an N × M  grid, where the square at the i-th row from the top and j -th column from the left has a non-negative integer Ai,j  written on it.

Let us choose a rectangular region R.


Formally, the region is chosen as follows.

Choose integers lx , rx , ly , ry  such that 1 ≤ lx ≤ rx ≤ N , 1 ≤ ly ≤ ry


​ ​ ​ ​ ​ ​ ​ ​ ≤ M.
Then, square (i, j) is in R if and only if lx ≤ i ≤ rx  and ly ≤ j ≤ ry .
​ ​ ​ ​

Find the maximum possible value of f (R) = (the sum of integers written on the squares in R) × (the smallest integer written on a square in R).

Constraints
All input values are integers.
1 ≤ N , M ≤ 300
1 ≤ Ai,j ≤ 300 ​

Input
The input is given from Standard Input in the following format:

N M
A1,1 A1,2 … A1,M
​ ​ ​

A2,1 A2,2 … A2,M


​ ​ ​


AN ,1 AN ,2 … AN ,M
​ ​

Output
Print the answer as an integer.

Sample Input 1  Copy

Copy
3 3
5 4 3
4 3 2
3 2 1

Sample Output 1  Copy

Copy
48

Choosing the rectangular region whose top-left corner is square (1, 1) and whose bottom-right corner is square (2, 2) achieves f (R) = (5 + 4 + 4 +
3) × min(5, 4, 4, 3) = 48, which is the maximum possible value.

Sample Input 2  Copy

Copy
4 5
3 1 4 1 5
9 2 6 5 3
5 8 9 7 9
3 2 3 8 4

Sample Output 2  Copy

Copy
231
Sample Input 3  Copy

Copy
6 6
1 300 300 300 300 300
300 1 300 300 300 300
300 300 1 300 300 300
300 300 300 1 300 300
300 300 300 300 1 300
300 300 300 300 300 1

Sample Output 3  Copy

Copy
810000
G. ONE MORE GRID TASK

Algorithm:

Step 1: Input the dimensions of the matrix 'a' (n x m).


Step 2: Input the elements of the matrix 'a'.
Step 3: Initialize a 2D vector 's' of size n x m to store the cumulative sums of the matrix 'a'.
Step 4: Compute the cumulative sums for each row of the matrix 'a' and store them in the corresponding
row of matrix 's'.
Step 5: Compute the cumulative sums for each column of the matrix 's'.
Step 6: Initialize a variable 'res' to store the maximum subgrid sum found so far. Set 'res' to 0 initially.
Step 7: For each potential height (mi) from 1 to 300, do the following:
Step 8: For each row (i) of the matrix 'a', do the following:
Step 9: Initialize a vector 'vp' to store the column indices of the current row, along with a value
representing the height of the column.
Step 10: For each column (j) in the current row, assign its height to 'vp[j].first' and store the column
index in 'vp[j].second'.
Step 11: Create two empty vectors 'top' and 'bot' to store the columns with heights greater than or equal
to 'mi' and less than 'mi', respectively.
Step 12: Traverse through 'vp', and based on the column heights, populate the 'top' and 'bot' vectors
accordingly.
Step 13: Reconstruct 'vp' by copying the columns from 'top' followed by columns from 'bot'. This is
done to have all columns with heights greater than or equal to 'mi' first.
Step 14: Initialize two arrays 'lef' and 'rig', representing the left and right neighbors of each column in
the current row.
Step 15: Traverse through 'vp', and for each column, update its left neighbor as 'lef[j] = j - 1' and its
right neighbor as 'rig[j] = j + 1'.
Step 16: Traverse through 'vp' again, and for each column, calculate the sum of the subgrid with the
top-left corner at (i - nx.first + 1, lef[nx.second] + 1) and the bottom-right corner at (i, rig[nx.second] -
1) using the 'sum2d' function.
Step 17: Update 'res' to be the maximum value between 'res' and 'cf * mi', where 'cf' is the sum calculated
in the previous step.
Step 18: Print the final maximum subgrid sum 'res'.
Step 19: End of the program.

Note: The code uses dynamic programming and prefix sums to efficiently calculate the sum of any
subgrid. It explores various possible heights ('mi') and calculates the maximum subgrid sum for each
height to find the overall maximum subgrid sum. The column heights are manipulated to consider only
columns with heights greater than or equal to 'mi' in each row, reducing the problem to 1D. The 1D
subgrid sum is then efficiently calculated using the 'sum2d' function. The overall time complexity of
the algorithm is O(n * m * 300), which is efficient given the constraints of the problem.

Code:

1. #include<bits/stdc++.h>
2.
3. using namespace std;
4.
5. int sum2d(int fx,int fy,int tx,int ty,vector<vector<int>> &s){
6. if(fx>tx || fy>ty){return 0;}
7. if(fx==0 && fy==0){return s[tx][ty];}
8. else if(fx==0){
9. return s[tx][ty]-s[tx][fy-1];
10. }
11. else if(fy==0){
12. return s[tx][ty]-s[fx-1][ty];
13. }
14. else{
15. return s[tx][ty]-s[tx][fy-1]-s[fx-1][ty]+s[fx-1][fy-1];
16. }
17. }
18.
19. int main(){
20. ios::sync_with_stdio(false);
21. cin.tie(nullptr);
22. int n,m;
23. cin >> n >> m;
24. vector<vector<int>> a(n,vector<int>(m));
25. for(int i=0;i<n;i++){
26. for(int j=0;j<m;j++){
27. cin >> a[i][j];
28. }
29. }
30. vector<vector<int>> s=a;
31. for(int i=1;i<n;i++){
32. for(int j=0;j<m;j++){s[i][j]+=s[i-1][j];}
33. }
34. for(int i=0;i<n;i++){
35. for(int j=1;j<m;j++){s[i][j]+=s[i][j-1];}
36. }
37.
38. long long res=0;
39. for(int mi=1;mi<=300;mi++){
40. vector<pair<int,int>> vp(m);
41. for(int i=0;i<m;i++){
42. vp[i].first=0;
43. vp[i].second=i;
44. }
45.
46. for(int i=0;i<n;i++){
47. vector<pair<int,int>> top,bot;
48. for(auto &nx : vp){
49. if(a[i][nx.second]>=mi){
50. top.push_back({nx.first+1,nx.second});
51. }
52. else{
53. bot.push_back({0,nx.second});
54. }
55. }
56. vp.clear();
57. for(auto &nx : top){vp.push_back(nx);}
58. for(auto &nx : bot){vp.push_back(nx);}
59.
60. vector<int> lef(m),rig(m);
61. for(int j=0;j<m;j++){
62. lef[j]=j-1;
63. rig[j]=j+1;
64. }
65.
66. for(auto &nx : vp){
67. int cl=lef[nx.second];
68. int cr=rig[nx.second];
69. if(cl>=0){rig[cl]=cr;}
70. if(cr<m){lef[cr]=cl;}
71. long long cf=sum2d(i-nx.first+1,cl+1,i,cr-1,s);
72. cf*=mi;
73. res=max(res,cf);
74. }
75. }
76. }
77. cout << res << "\n";
78. return 0;
79. }
Ex - Many Illumination Plans  Editorial
 / 

Time Limit: 3 sec / Memory Limit: 1024 MB

Score : 675 points

Problem Statement
There is a rooted tree T  with N  vertices numbered 1 to N . The root is vertex 1, and the parent of vertex i (2 ≤ i ≤ N ) is Pi .

Each vertex has two non-negative integer values called beauty and weight. The beauty and weight of vertex i are Bi  and Wi , respectively.
​ ​

Additionally, each vertex is painted red or blue. The color of vertex i is represented by an integer Ci : vertex i is painted red if Ci
​ ​ = 0, and blue if Ci = 1.

For vertex v , let F (v) be the answer to the following problem.

Let U  be the rooted tree that is the subtree of T  rooted at v .
You can perform the following sequence of operations on U  zero or more times. (The operations do not affect the beauties, weights, or colors of
the vertices that are not being deleted.)

Choose a vertex c other than the root. Let p be the parent of c.


For each edge whose endpoint on the parent side is c, do the following:
Let u be the endpoint of the edge other than c. Delete the edge and connect p and u with a new edge, with p on the parent side.
Delete the vertex c, and the edge connecting p and c.

A rooted tree that can be obtained as U  after some operations is called a good rooted tree when all of the following conditions are satisfied.

For every edge in U , the edge's endpoints have different colors.
The vertices have a total weight of at most X .

Find the maximum possible total beauty of the vertices in a good rooted tree.

Find all of F (1), F (2), … , F (N ).

Constraints
2 ≤ N ≤ 200
0 ≤ X ≤ 50000
1 ≤ Pi ≤ i − 1 ​

0 ≤ Bi ≤ 1015 ​

0 ≤ Wi ≤ X ​

Ci  is 0 or 1.

All input values are integers.

Input
The input is given from Standard Input in the following format:

N X
P2 ​
P3 … PN
​ ​

B1 ​ W 1 C1 ​ ​

B2 ​ W 2 C2 ​ ​


BN W N C N
​ ​ ​

Output
Print N  lines. The i-th line should contain F (i).

Sample Input 1  Copy

Copy
4 10
1 2 2
2 1 0
4 2 1
6 8 0
7 4 1
Sample Output 1  Copy

Copy
9
10
6
7

For v = 1, choosing c = 2 and then c = 3 changes U  as shown in the figure, making it a good rooted tree. The total beauty of the vertices in this tree
is 2 + 7 = 9, which is the maximum among all good rooted trees, so F (1) = 9.

For v = 2, choosing c = 4 changes U  as shown in the figure, making it a good rooted tree. The total beauty of the vertices in this tree is 4 + 6 = 10,
which is the maximum among all good rooted trees, so F (2) = 10.

Sample Input 2  Copy

Copy
5 5
1 2 2 3
1 1 0
10 1 1
100 1 0
1000 1 1
10000 1 1

Sample Output 2  Copy

Copy
11001
10110
10100
1000
10000

Sample Input 3  Copy

Copy
20 100
1 2 1 1 1 6 6 5 1 7 9 4 6 4 15 16 8 2 5
887945036308847 12 0
699398807312293 20 1
501806283312516 17 0
559755618233839 19 1
253673279319163 10 1
745815685342299 11 1
251710263962529 15 0
777195295276573 15 0
408579800634972 17 0
521840965162492 17 1
730678137312837 18 1
370007714721362 14 1
474595536466754 17 0
879365432938644 15 0
291785577961862 20 0
835878893889428 14 1
503562238579284 10 0
567569163005307 18 1
368949585722534 15 0
386435396601075 16 0

Sample Output 3  Copy

Copy
5329161389647368
1570154676347343
501806283312516
2665577865131167
1418696191276572
3952333977838189
982388401275366
1344764458281880
778587515356334
521840965162492
730678137312837
370007714721362
474595536466754
879365432938644
1631226710430574
1339441132468712
503562238579284
567569163005307
368949585722534
386435396601075
Ex – Many Illumina on Plans:

Algorithm:

Step 1: The func on takes a node 'c' as input, which represents a node in a tree data structure.

Step 2: Ini alize two DP tables, `Dp[0]` and `Dp[1]`, to store intermediate results. These DP tables are
represented as arrays.

Step 3: Base case: If 'c' is a leaf node (i.e., it has no children), ini alize both `Dp[0]` and `Dp[1]` to be
the DP table corresponding to the empty set (essen ally, all values in the table are ini alized to a
neutral value, like -infinity).

Step 4: Recursive case: For each child node 'd' of the current node 'c', recursively call the `dfs(d)`
func on to obtain the DP tables `ep[0]` and `ep[1]` for the child node 'd'. These tables will store the
op mal results for the subtree rooted at node 'd'.

Step 5: Merge results from child nodes: Update the DP table `Dp[0]` by performing the max-plus
convolu on with `ep[0]` for all child nodes 'd'. This means taking the element-wise maximum of the
two tables. Similarly, update `Dp[1]` using the max-plus convolu on with `ep[1]`.

Step 6: Perform DP transi on for the current node 'c': For each possible value of 'i' from 0 to (X - W[c]),
where 'X' is a predefined constant and 'W[c]' is the weight of the current node 'c', update the DP table
`Dp[C[c]][i + W[c]]` by taking the maximum value between its current value and the value of `Dp[1 -
C[c]][i] + B[c]`. Here, 'C[c]' represents the type of the current node 'c' (either 0 or 1), and 'B[c]' is a
predefined constant represen ng some value associated with the node 'c'.

Step 7: Return the DP table `Dp`, which now contains the op mal results for the subtree rooted at the
current node 'c'.

Step 8: The algorithm will con nue to execute for all other nodes in the tree, following the recursive
approach, and the final DP tables `Dp[0]` and `Dp[1]` will contain the op mal results for the en re
tree.

Code:

1. function dfs(c):
2. Dp[0] <- (DP table corresponding to empty set)
3. Dp[1] <- (DP table corresponding to empty set)
4. for d in {children of c} do
5. ep = dfs(d)
6. Dp[0] <- max_plus_convolution(Dp[0], ep[0])
7. Dp[1] <- max_plus_convolution(Dp[1], ep[1])
8. end for
9. for i = 0 to X - W[c] do
10. chmax(Dp[C[c]][i + W[c]], Dp[1 - C[c]][i] + B[c])
11. end for
12. return Dp
A DETAILED EDITORIAL FOR
ATCODER - UNIQUE VISION PROGRAMMING
CONTEST 2023 SUMMER(ATCODER BEGINNER
CONTEST 312)

Date of Contest: 29-07-2023

Editorial by
Dr. Dinesh Kumar Anguraj, Asso. Prof., Dept. of CSE.
Website Link: https://atcoder.jp/

Contest URL: https://atcoder.jp/contests/abc312

Mode: Rated & Unrated

Number of Contest Tasks: 7 Tasks

Number of Extra Tasks: 1 Task

Note & Credits: Problem statement and Hints from Atcoder.jp by the users
“en_translator (English) & physics (Japanese)”
CONTEST PROBLEM
STATEMENTS, HINTS AND
ALGORITHMS WITH CODE
A - Chord  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 100 points

Problem Statement
Given a length-3 string S  consisting of uppercase English letters, print Yes if S  equals one
of ACE, BDF, CEG, DFA, EGB, FAC, and GBD; print No otherwise.

Constraints
S  is a length-3 string consisting of uppercase English letters.

Input
The input is given from Standard Input in the following format:

Output
Print Yes if S  equals one of ACE, BDF, CEG, DFA, EGB, FAC, and GBD; print No otherwise.

Sample Input 1  Copy

Copy
ABC

Sample Output 1  Copy

Copy
No

When S = ABC, S  does not equal any of ACE, BDF, CEG, DFA, EGB, FAC, and GBD, so No should be printed.

Sample Input 2  Copy

Copy
FAC
Sample Output 2  Copy

Copy
Yes

Sample Input 3  Copy

Copy
XYX

Sample Output 3  Copy

Copy
No
A – Chord

Algorithm:

1. Start the program.


2. Declare a string variable s to store the input string from the user.
3. Prompt the user to enter a string and read the input into the variable s.
4. Declare a string variable t and initialize it with the value "ACEGBDFAC".
5. Search for the substring s in the string t using the find() function.
6. If the find() function returns string::npos (indicating that the substring s
was not found in t), go to step 9.
7. If the find() function returns an index other than string::npos (indicating
that the substring s was found in t), go to step 10.
8. Output "Yes" to the console, indicating that the input string s exists in the
predefined string t.
9. Output "No" to the console, indicating that the input string s does not exist in
the predefined string t .
10. End the program.

In summary, the algorithm determines whether the input string s exists in the
predefined string t. If it does, the program outputs "Yes"; otherwise, it outputs "No"
to the console.

Code:

#include <iostream>

#include <string>

using namespace std;

int main()

string s;

cin >> s;

if (s == "ACE" or s == "BDF" or s == "CEG" or s == "DFA" or s == "EGB" or s == "FAC" or s ==


"GBD") cout << "Yes\n";

else cout << "No\n";

(OR)
#include <iostream>

#include <string>

using namespace std;

int main()

string s;

cin >> s;

string t = "ACEGBDFAC";

cout << (t.find(s) == string::npos ? "No" : "Yes") << '\n';

}
B - TaK Code  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 200 points

Problem Statement
Takahashi invented Tak Code, a two-dimensional code. A TaK Code satisfies all of the following
conditions:

It is a region consisting of nine horizontal rows and nine vertical columns.


All the 18 cells in the top-left and bottom-right three-by-three regions are black.
All the 14 cells that are adjacent (horizontally, vertically, or diagonally) to the top-left or bottom-right
three-by-three region are white.

It is not allowed to rotate a TaK Code.

You are given a grid with N  horizontal rows and M  vertical columns. The state of the grid is described
by N  strings, S1 , …, and SN , each of length M . The cell at the i-th row from the top and j -th column
​ ​

from the left is black if the j -th character of Si  is #, and white if it is ..

Find all the nine-by-nine regions, completely contained in the grid, that satisfy the conditions of a TaK
Code.

Constraints
9 ≤ N , M ≤ 100
N  and M  are integers.
Si  is a string of length M  consisting of . and #.

Input
The input is given from Standard Input in the following format:

N M
S1 ​


SN ​

Output
For all pairs (i, j) such that the nine-by-nine region, whose top-left cell is at the i-th row from the top and 
j -th columns from the left, satisfies the conditions of a TaK Code, print a line containing i, a space, and j
 in this order.
The pairs must be sorted in lexicographical ascending order; that is, i must be in ascending order, and
within the same i, j  must be in ascending order.

Sample Input 1  Copy

Copy
19 18
###......###......
###......###......
###..#...###..#...
..............#...
..................
..................
......###......###
......###......###
......###......###
.###..............
.###......##......
.###..............
............###...
...##.......###...
...##.......###...
.......###........
.......###........
.......###........
........#.........

Sample Output 1  Copy

Copy
1 1
1 10
7 7
10 2

A TaK Code looks like the following, where # is a black cell, . is a white cell, and ? can be either black or
white.

###.?????
###.?????
###.?????
....?????
?????????
?????....
?????.###
?????.###
?????.###

In the grid given by the input, the nine-by-nine region, whose top-left cell is at the 10-th row from the top
and 2-nd column from the left, satisfies the conditions of a TaK Code, as shown below.
###......
###......
###......
.........
..##.....
..##.....
......###
......###
......###

Sample Input 2  Copy

Copy
9 21
###.#...........#.###
###.#...........#.###
###.#...........#.###
....#...........#....
#########...#########
....#...........#....
....#.###...###.#....
....#.###...###.#....
....#.###...###.#....

Sample Output 2  Copy

Copy
1 1

Sample Input 3  Copy

Copy
18 18
######............
######............
######............
######............
######............
######............
..................
..................
..................
..................
..................
..................
............######
............######
............######
............######
............######
............######
Sample Output 3  Copy

Copy

There may be no region that satisfies the conditions of TaK Code.


B - TaK Code

Algorithm:

1. Start the program.


2. Declare a 2D character array s to store the grid of size 110x110.
3. Read the values of n and m representing the dimensions of the grid (n rows
and m columns).
4. Read the grid input by scanning each row of characters into the s array.
5. Define a function check that takes two parameters i and j representing the
starting position (row and column) of a 3x3 region in the grid.
6. The function check checks for a specific pattern in the 3x3 and 4x4 regions:
 It ensures that all characters in the 3x3 region and its mirrored
counterpart are '#'. Otherwise, it returns 0.
 It checks that the middle row and middle column of the 3x3 region are
all '.' characters. If not, it returns 0.
 It checks that the middle row of the 4x4 region (row 3) contains all '.'
characters. If not, it returns 0.
 It checks that the middle column of the 4x4 region (column 3) contains
all '.' characters. If not, it returns 0.
 If all conditions are met, it returns 1, indicating that the pattern is
found.
7. In the main function, iterate through each possible 3x3 region in the grid
(from (0,0) to (n-9,m-9)), and for each region, do the following:
 Call the check function with the current position (i, j) as arguments.
 If the check function returns 1 (indicating the pattern is found), output
the starting position (i+1, j+1) as the result. Note: Adding 1 is because
the positions are 0-indexed in the grid but need to be 1-indexed in the
output.
8. End the program.

The code essentially searches for a specific pattern in the given grid and outputs the
starting positions of regions that match that pattern. The pattern is composed of '#'
characters forming two mirrored 3x3 regions and a central 4x4 region with '.'
characters in certain positions.

Code:

1. #include<stdio.h>
2.
3. char s[110][110];
4. int check(int i,int j){
5. for(int ii=0;ii<3;ii++)for(int
jj=0;jj<3;jj++)if(s[i+ii][j+jj]!='#')return 0;
6. for(int ii=0;ii<3;ii++)for(int jj=0;jj<3;jj++)if(s[i+8-ii][j+8-
jj]!='#')return 0;
7. for(int ii=0;ii<4;ii++)if(s[i+ii][j+3]!='.')return 0;
8. for(int jj=0;jj<4;jj++)if(s[i+3][j+jj]!='.')return 0;
9. for(int ii=0;ii<4;ii++)if(s[i+8-ii][j+8-3]!='.')return 0;
10. for(int jj=0;jj<4;jj++)if(s[i+8-3][j+8-jj]!='.')return 0;
11. return 1;
12. }
13. int main(){
14. int n,m;
15. scanf("%d%d",&n,&m);
16. for(int i=0;i<n;i++)scanf("%s",s[i]);
17. for(int i=0;i<n-8;i++)for(int j=0;j<m-8;j++){
18. if(check(i,j))printf("%d %d\n",i+1,j+1);
19. }
20. }
C - Invisible Hand  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 300 points

Problem Statement
There are N  sellers and M  buyers in an apple market.

The i-th seller may sell an apple for Ai  yen or more (yen is the currency in Japan).

The i-th buyer may buy an apple for Bi  yen or less.


Find the minimum integer X  that satisfies the following condition.

Condition: The number of people who may sell an apple for X  yen is greater than or equal to the number
of people who may buy an apple for X  yen.

Constraints
1 ≤ N , M ≤ 2 × 105
1 ≤ Ai , Bi ≤ 109
​ ​

All input values are integers.

Input
The input is given from Standard Input in the following format:

N M
A1 … AN
​ ​

B1 … BM
​ ​

Output
Print the answer.

Sample Input 1  Copy

Copy
3 4
110 90 120
100 80 120 10000
Sample Output 1  Copy

Copy
110

Two sellers, the 1-st and 2-nd, may sell an apple for 110 yen; two buyers, the 3-rd and 4-th, may buy an
apple for 110 yen. Thus, 110 satisfies the condition.

Since an integer less than 110 does not satisfy the condition, this is the answer.

Sample Input 2  Copy

Copy
5 2
100000 100000 100000 100000 100000
100 200

Sample Output 2  Copy

Copy
201

Sample Input 3  Copy

Copy
3 2
100 100 100
80 120

Sample Output 3  Copy

Copy
100
C - Invisible Hand

Algorithm:

1. Read two space-separated integers N and M from input. These integers


represent the size of the lists A and B, respectively.
2. Read space-separated integers and store them in list A.
3. Read space-separated integers and store them in list B.
4. Map a lambda function to each element in list B, which adds 1 to each
element. This results in a new list containing B elements incremented by 1.
5. Concatenate list A and the new list containing B elements incremented by 1
using the '+' operator.
6. Sort the concatenated list in ascending order.
7. Print the M-th element from the sorted list (0-indexed).

In summary, the code takes two lists A and B as input, increments each element in B
by 1, merges both lists, sorts the merged list, and then prints the M-th element (0-
indexed) from the sorted list.

Note: The sorting and indexing are zero-indexed in Python, so the M-th element will
be printed as the (M - 1)-th element in the list.

Code:

N, M = map(int, input().split())

A = list(map(int, input().split()))

B = list(map(int, input().split()))

print(sorted(A + list(map(lambda x: x + 1, B)))[M - 1])


D - Count Bracket Sequences  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 400 points

Problem Statement
You are given a non-empty string S  consisting of (, ), and ?.
There are 2x  ways to obtain a new string by replacing each ? in S  with ( and ), where x is the number of
occurrences of ? in S . Among them, find the number, modulo 998244353, of ways that yield
a parenthesis string.

A string is said to be a parenthesis string if one of the following conditions is satisfied.

It is an empty string.
It is a concatenation of (, A, and ), for some parenthesis string A.
It is a concatenation of A and B , for some non-empty parenthesis strings A and B .

Constraints
S  is a non-empty string of length at most 3000 consisting of (, ), and ?.

Input
The input is given from Standard Input in the following format:

Output
Print the answer.

Sample Input 1  Copy

Copy
(???(?

Sample Output 1  Copy

Copy
2

Replacing S  with ()()() or (())() yields a parenthesis string.


The other replacements do not yield a parenthesis string, so 2 should be printed.
Sample Input 2  Copy

Copy
)))))

Sample Output 2  Copy

Copy
0

Sample Input 3  Copy

Copy
??????????????(????????(??????)?????????(?(??)

Sample Output 3  Copy

Copy
603032273

Print the count modulo 998244353.


D - Count Bracket Sequences

Algorithm:

This C++ code utilizes the atcoder library to compute the number of ways to form
balanced parentheses expressions using a given string s. The algorithm uses dynamic
programming to achieve this efficiently.

Here's a step-by-step explanation of the code:

1. Include the necessary C++ libraries:


 <iostream>: For standard input/output operations.
 <string>: For string handling.
 <vector>: For working with vectors (2D dynamic arrays).
 <atcoder/modint>: For using a modular arithmetic library provided by
atcoder, specifically static_modint, which allows calculations modulo a
prime number.
2. Create an alias mint for the type atcoder::static_modint<998244353>. This
alias will represent modular integers using modulo 998244353.
3. The main() function starts here.
4. Read a string s from the user.
5. Obtain the size of the string s and store it in the variable n.
6. Create a 2D vector dp with dimensions (n+1) x (n+1) to store intermediate
results during dynamic programming. All elements are initialized to zero.
7. Set dp[0][0] to 1, representing the base case when there are no parentheses.
8. Perform dynamic programming to count the number of ways to form balanced
parentheses expressions:
 For each character s[i] in the string s (0-indexed):
 If s[i] is not equal to ')', add the value of dp[i][j] to
dp[i+1][j+1]. This represents adding an opening parenthesis '('.
 If j is not zero (to ensure a closing parenthesis can be matched),
and s[i] is not equal to '(', add the value of dp[i][j] to
dp[i+1][j-1]. This represents adding a closing parenthesis ')'.
9. After the dynamic programming loop, the value of dp[n][0] represents the
total number of ways to form balanced parentheses expressions using the entire
string s.
10. Print the result of dp[n][0] modulo 998244353 using val().
11. End the program.

In summary, the code efficiently calculates the number of ways to form balanced
parentheses expressions using the given string s using a dynamic programming
approach and modular arithmetic. The answer is printed modulo 998244353.
Code:

#include <iostream>

#include <string>

#include <vector>

#include <atcoder/modint>

using namespace std;

using mint = atcoder::sta c_modint<998244353>;

int main() {

string s;

cin >> s;

int n = s.size();

vector<vector<mint>> dp(n + 1, vector<mint>(n + 1));

dp[0][0] = 1;

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

for (int j = 0; j < n; j++) {

if (s[i] != ')') dp[i + 1][j + 1] += dp[i][j];

if (j != 0 && s[i] != '(') dp[i + 1][j - 1] += dp[i][j];

cout << dp[n][0].val() << '\n';

}
E - Tangency of Cuboids  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 500 points

Problem Statement
There are N  rectangular cuboids in a three-dimensional space.

These cuboids do not overlap. Formally, for any two different cuboids among them, their intersection has
a volume of 0.

The diagonal of the i-th cuboid is a segment that connects two points (Xi,1 , Yi,1 , Zi,1 ) and  ​ ​

(Xi,2 , Yi,2 , Zi,2 ), and its edges are all parallel to one of the coordinate axes.
​ ​ ​

For each cuboid, find the number of other cuboids that share a face with it.
Formally, for each i, find the number of j  with 1 ≤ j ≤ N  and j =
 i such that the intersection of the
surfaces of the i-th and j -th cuboids has a positive area.

Constraints
1 ≤ N ≤ 105
0 ≤ Xi,1 < Xi,2 ≤ 100​ ​

0 ≤ Yi,1 < Yi,2 ≤ 100


​ ​

0 ≤ Zi,1 < Zi,2 ≤ 100


​ ​

Cuboids do not have an intersection with a positive volume.


All input values are integers.

Input
The input is given from Standard Input in the following format:

N
X1,1 Y1,1 Z1,1 X1,2 Y1,2 Z1,2
​ ​ ​ ​ ​ ​


XN ,1 YN ,1 ZN ,1 XN ,2 YN ,2 ZN ,2
​ ​ ​ ​ ​ ​

Output
Print the answer.
Sample Input 1  Copy

Copy
4
0 0 0 1 1 1
0 0 1 1 1 2
1 1 1 2 2 2
3 3 3 4 4 4

Sample Output 1  Copy

Copy
1
1
0
0

The 1-st and 2-nd cuboids share a rectangle whose diagonal is the segment connecting two points 
(0, 0, 1) and (1, 1, 1).
The 1-st and 3-rd cuboids share a point (1, 1, 1), but do not share a surface.

Sample Input 2  Copy

Copy
3
0 0 10 10 10 20
3 4 1 15 6 10
0 9 6 1 20 10

Sample Output 2  Copy

Copy
2
1
1

Sample Input 3  Copy

Copy
8
0 0 0 1 1 1
0 0 1 1 1 2
0 1 0 1 2 1
0 1 1 1 2 2
1 0 0 2 1 1
1 0 1 2 1 2
1 1 0 2 2 1
1 1 1 2 2 2

Sample Output 3  Copy


Copy
3
3
3
3
3
3
3
3
E - Tangency of Cuboids

Algorithm:

This C++ code reads information about cuboids and calculates the number of distinct
neighbors each cuboid has in a 3D grid. The add function is used to keep track of
neighboring relationships between the cuboids.

Let's break down the code step-by-step:

1. Include the necessary C++ standard library (<bits/stdc++.h>).


2. Define the macro rep(i,l,r) as a shorthand for a for-loop with an increment
of 1. It iterates from l (inclusive) to r (exclusive).
3. Declare a 3D integer array a with dimensions 110x110x110. This array will be
used to store the cuboids' information.
4. The main() function starts here.
5. Read the number of cuboids n from the user.
6. Loop n times to read the cuboid information for each cuboid:
 Read the coordinates (x1, y1, z1) of the cuboid's first corner (lower
coordinate) and (x2, y2, z2) of the cuboid's second corner (upper
coordinate).
 Set the corresponding elements in the a array with the cuboid's index i
+ 1 (since the cuboid indices are 1-based).
7. Create a vector of sets called ans to store the neighbors for each cuboid. The
ans[i] set will contain the indices of the cuboids that are neighbors with cuboid
i.
8. Define a lambda function add that takes two integers i and j. This function
adds j to the set of neighbors for cuboid i, and vice versa.
9. Loop over the entire 3D grid (from 0 to 99 in each dimension) to find
neighboring relationships:
 If the current cell (a[x][y][z]) is non-zero (i.e., there's a cuboid):
 Check adjacent cells (right, top, and front) and add neighboring
relationships to the ans set using the add function.
10. Finally, loop from 1 to n and output the size of the neighbor set for each cuboid.

In summary, the code reads information about cuboids and their coordinates in a 3D
grid. It then determines the neighboring relationships between these cuboids and
outputs the number of distinct neighbors each cuboid has. The neighboring
relationship is established based on the adjacency of cuboid faces (sharing a common
boundary).

Code:

#include<bits/stdc++.h>
using namespace std;

#define rep(i,l,r)for(int i=(l);i<(r);i++)

int a[110][110][110];

int main(){

int n;

cin >> n;

rep(i,0,n){

int x1,y1,z1,x2,y2,z2;

cin >> x1 >> y1 >> z1 >> x2 >> y2 >> z2;

rep(x,x1,x2)rep(y,y1,y2)rep(z,z1,z2)a[x][y][z]=i+1;

vector<set<int>>ans(n+1);

auto add=[&](int i,int j){

ans[i].insert(j);

ans[j].insert(i);

};

rep(x,0,100)rep(y,0,100)rep(z,0,100)if(a[x][y][z]){

if(a[x+1][y][z]&&a[x+1][y][z]!=a[x][y][z])add(a[x][y][z],a[x+1][y][z]);

if(a[x][y+1][z]&&a[x][y+1][z]!=a[x][y][z])add(a[x][y][z],a[x][y+1][z]);

if(a[x][y][z+1]&&a[x][y][z+1]!=a[x][y][z])add(a[x][y][z],a[x][y][z+1]);

rep(i,1,n+1)cout << ans[i].size() << endl;

}
F - Cans and Openers  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 500 points

Problem Statement
There are N  items.
Each of these is one of a pull-tab can, a regular can, or a can opener.
The i-th item is described by an integer pair (Ti , Xi ) as follows:
​ ​

If Ti = 0, the i-th item is a pull-tab can; if you obtain it, you get a happiness of Xi .
​ ​

If Ti = 1, the i-th item is a regular can; if you obtain it and use a can opener against it, you get a

happiness of Xi . ​

If Ti = 2, the i-th item is a can opener; it can be used against at most Xi  cans.
​ ​

Find the maximum total happiness that you get by obtaining M  items out of N .

Constraints
1 ≤ M ≤ N ≤ 2 × 105
Ti  is 0, 1, or 2.

1 ≤ Xi ≤ 109 ​

All input values are integers.

Input
The input is given from Standard Input in the following format:

N M
T 1 X1
​ ​

T 2 X2
​ ​


T N XN ​ ​

Output
Print the answer as an integer.

Sample Input 1  Copy

Copy
8 4
0 6
0 6
1 3
1 5
1 15
2 1
2 10
2 100

Sample Output 1  Copy

Copy
27

If you obtain the 1-st, 2-nd, 5-th, and 7-th items, and use the 7-th item (a can opener) against the 5-th
item, you will get a happiness of 6 + 6 + 15 = 27.
There are no ways to obtain items to get a happiness of 28 or greater, but you can still get a happiness
of 27 by obtaining the 6-th or 8-th items instead of the 7-th in the combination above.

Sample Input 2  Copy

Copy
5 5
1 5
1 5
1 5
1 5
1 5

Sample Output 2  Copy

Copy
0

Sample Input 3  Copy

Copy
12 6
2 2
0 1
0 9
1 3
1 5
1 3
0 4
2 1
1 8
2 1
0 1
0 4

Sample Output 3  Copy

Copy
30
E - Tangency of Cuboids

Algorithm:

This code seems to be a C++ program that reads the information about cuboids
defined by their opposite corners' coordinates and calculates the number of distinct
neighbors for each cuboid. The code uses a 3D grid to represent the cuboids and
utilizes a vector of sets to store neighboring relationships between them.

Let's break down the code step-by-step:

1. Include the necessary C++ standard library (<bits/stdc++.h>).


2. Define the macro rep(i,l,r) as a shorthand for a for-loop with an increment
of 1. It iterates from l (inclusive) to r (exclusive).
3. Declare a 3D integer array a with dimensions 110x110x110. This array will be
used to represent the 3D grid where cuboids are placed.
4. The main() function starts here.
5. Read the integer n from the user, which represents the number of cuboids.
6. Loop n times to read the information for each cuboid: a. Read the coordinates
(x1, y1, z1) of the cuboid's first corner (lower coordinate) and (x2, y2, z2) of the
cuboid's second corner (upper coordinate). b. For each cell (x, y, z) within the
cuboid's defined region (x1 <= x < x2, y1 <= y < y2, z1 <= z < z2), mark it with
the cuboid's index i + 1 in the 3D grid a. This step essentially assigns a unique
index to each cuboid in the grid.
7. Create a vector of sets called ans to store the neighbors for each cuboid. The
ans[i] set will contain the indices of the cuboids that are neighbors with cuboid
i.
8. Define a lambda function add that takes two integers i and j. This function
adds j to the set of neighbors for cuboid i, and vice versa, effectively creating
a bidirectional relationship.
9. Iterate over each cell in the 3D grid (x, y, z) within the range [0, 99] (inclusive)
and check for neighboring relationships between cuboids: a. If the current cell
(a[x][y][z]) contains a cuboid index (non-zero value):
 Check the neighboring cells (right, top, and front) (x+1, y), (x, y+1), and
(x, y, z+1) for potential neighbors.
 If the neighboring cell contains a different cuboid index than the current
cell, add neighboring relationships between the cuboids using the add
function.
10. After creating all the neighboring relationships, the ans vector contains the sets
of neighbors for each cuboid.
11. Loop from 1 to n and output the size of the neighbor set for each cuboid, which
represents the number of distinct neighbors for that cuboid.
12. End the program.
In summary, the code reads information about cuboids and their coordinates in a 3D
grid. It then determines the neighboring relationships between these cuboids and
outputs the number of distinct neighbors each cuboid has. The neighboring
relationship is established based on the adjacency of cuboid faces (sharing a common
boundary).

Code:

#include<bits/stdc++.h>

using namespace std;

#define rep(i,l,r)for(int i=(l);i<(r);i++)

int a[110][110][110];

int main(){

int n;

cin >> n;

rep(i,0,n){

int x1,y1,z1,x2,y2,z2;

cin >> x1 >> y1 >> z1 >> x2 >> y2 >> z2;

rep(x,x1,x2)rep(y,y1,y2)rep(z,z1,z2)a[x][y][z]=i+1;

vector<set<int>>ans(n+1);

auto add=[&](int i,int j){

ans[i].insert(j);

ans[j].insert(i);

};

rep(x,0,100)rep(y,0,100)rep(z,0,100)if(a[x][y][z]){

if(a[x+1][y][z]&&a[x+1][y][z]!=a[x][y][z])add(a[x][y][z],a[x+1][y][z]);

if(a[x][y+1][z]&&a[x][y+1][z]!=a[x][y][z])add(a[x][y][z],a[x][y+1][z]);

if(a[x][y][z+1]&&a[x][y][z+1]!=a[x][y][z])add(a[x][y][z],a[x][y][z+1]);

}
rep(i,1,n+1)cout << ans[i].size() << endl;

}
G - Avoid Straight Line  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 550 points

Problem Statement
You are given a tree with N  vertices. The vertices are numbered from 1 through N , and the i-th edge
connects vertex Ai  and vertex Bi .
​ ​

Find the number of tuples of integers (i, j, k) such that:

1 ≤ i < j < k ≤ N ; and


the given tree does not contain a simple path that contains all of vertices i, j , and k .

Constraints
1 ≤ N ≤ 2 × 105
1 ≤ Ai , Bi ≤ N
​ ​

The given graph is a tree.


All input values are integers.

Input
The input is given from Standard Input in the following format:

N
A1 B1
​ ​


AN −1 BN −1
​ ​

Output
Print the answer.

Sample Input 1  Copy

Copy
5
1 2
2 3
2 4
1 5
Sample Output 1  Copy

Copy
2

Two tuples satisfy the conditions: (i, j, k) = (1, 3, 4), (3, 4, 5).

Sample Input 2  Copy

Copy
6
1 2
2 3
3 4
4 5
5 6

Sample Output 2  Copy

Copy
0

Sample Input 3  Copy

Copy
12
1 6
3 4
10 4
5 9
3 1
2 3
7 2
2 12
1 5
6 8
4 11

Sample Output 3  Copy

Copy
91
G - Avoid Straight Line

Algorithm:

This C++ code is an implementation that calculates the number of triplets of vertices
(u, v, w) in an undirected tree, where u, v, and w are connected by edges. It efficiently
computes the answer by using depth-first search (DFS) and dynamic programming on
trees.

Here's a step-by-step explanation of the code:

1. Include the necessary C++ standard library (<bits/stdc++.h>).


2. Create aliases for long long and vector<vector<int>> for easier readability.
3. The main() function starts here.
4. Disable synchronization between C++ standard streams and C-style streams to
improve I/O performance.
5. Create variables n and T to store the number of vertices and the tree structure,
respectively.
6. Read the number of vertices n from input.
7. Initialize the tree vector T with n empty vectors, where T[i] represents the
neighbors of vertex i.
8. Read the edges of the tree (n-1 edges) and populate the tree vector T
accordingly. The tree edges are given in the form of undirected edges (u, v).
9. Calculate the initial value of ans using the formula: n * (n - 1) * (n - 2) /
6. This represents the total number of possible triplets of vertices in a complete
graph of n vertices.
10. Create a vector sz of size n to store the size of each subtree rooted at each
vertex.
11. Define a lambda function dfs to perform the depth-first search and dynamic
programming on the tree.
12. Inside the dfs function: a. Calculate the sizes of the subtrees and the number
of vertices in the tree rooted at each vertex. b. Compute the sum of squares of
subtree sizes in sum2 and the sum of subtree sizes in sum1. c. Update ans by
subtracting the sum of (sum1 * sum1 - sum2) / 2 from it. This step removes
the triplets that contain the current vertex and considers only the triplets formed
by vertices from different subtrees.
13. Call the dfs function starting from the root vertex (0) with a parent (-1)
indicating that there is no parent for the root.
14. Output the final value of ans.
15. End the program.

In summary, the code efficiently calculates the number of triplets of vertices (u, v, w)
in an undirected tree using DFS and dynamic programming on trees. It avoids
unnecessary computations and leverages the tree structure to obtain the result in an
optimal way.

Code:

1. #include <bits/stdc++.h>
2. using namespace std;
3.
4. using ll=long long;
5.
6. int main(){
7. ios::sync_with_stdio(false);
8. cin.tie(nullptr);
9.
10. ll n;cin>>n;
11. vector<vector<int>> T(n);
12. for(int _=0;_<n-1;_++){
13. int u,v;cin>>u>>v;u--;v--;
14. T[u].push_back(v);
15. T[v].push_back(u);
16. }
17.
18. ll ans=n*(n-1)*(n-2)/6;
19.
20. vector<ll> sz(n,1);
21. auto dfs=[&](auto dfs,int v,int pre)->void{
22. ll sum1=0,sum2=0;
23. for(int c:T[v]){
24. if(c==pre)continue;
25. dfs(dfs,c,v);
26. sum1 += sz[c];
27. sum2 += sz[c]*sz[c];
28. sz[v]+=sz[c];
29. }
30. sum1 += n-sz[v];
31. sum2 += (n-sz[v])*(n-sz[v]);
32. ans -= (sum1*sum1 - sum2) >> 1;
33. };
34. dfs(dfs,0,-1);
35.
36. cout<<ans<<'\n';
37. }
Ex - snukesnuke  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 600 points

Problem Statement
Takahashi is going to decide nicknames of N  people, person 1, … , N .

Person i wants a nickname Si . To avoid giving the same nickname to multiple people, he is going to

decide their nicknames as follows:

For each i = 1, … , N  in order, decide person i's nickname as follows:


Initialize a variable ki  with 1. ​

Repeatedly increment ki  by one while the ki -time repetition of Si  is someone's nickname.
​ ​ ​

Let person i's nickname be the ki -time repetition of Si .


​ ​

Find k1 , …, and kN  after deciding nicknames of the N  people.


​ ​

Constraints
N ≥1
Si  is a string of length at least 1 consisting of lowercase English letters.

The sum of lengths of Si  is at most 2 × 105 .


Input
The input is given from Standard Input in the following format:

N
S1 ​


SN ​

Output
Print k1 , …, and kN  resulting from deciding the nicknames of the N  people by the procedure in the
​ ​

problem statement.

Sample Input 1  Copy

Copy
3
snuke
snuke
rng

Sample Output 1  Copy

Copy
1 2 1

First, he decides person 1's nickname.


Let k1 ​ = 1.
The k1 -time repetition of S1  is snuke, which is nobody's nickname, so person 1's nickname is
​ ​

set to snuke.
Next, he decides person 2's nickname.
Let k2 = 1.​

The k2 -time repetition of S2  is snuke, which is already a nickname of person 1, so increment 
​ ​

k2  by one to make it 2.


The k2 -time repetition of S2  is snukesnuke, which is nobody's nickname, so person 2's


​ ​

nickname is set to snukesnuke.


Finally, he decides person 3's nickname.
Let k3 = 1.​

The k3 -time repetition of S3  is rng, which is nobody's nickname, so person 3's nickname is
​ ​

set to rng.

Thus, k1 , k2 , and k3  result in 1, 2, and 1, respectively.


​ ​ ​

Sample Input 2  Copy

Copy
4
aa
a
a
aaa

Sample Output 2  Copy

Copy
1 1 3 2

Person 1's nickname is set to aa.


Person 2's nickname is set to a.
Person 3's nickname is set to aaa, because a and aa are already nicknames of someone else.
Person 4's nickname is set to aaaaaa, because aaa is already a nickname of someone else.
Sample Input 3  Copy

Copy
5
x
x
x
x
x

Sample Output 3  Copy

Copy
1 2 3 4 5
Ex – snukesnuke

Algorithm:

This C++ code calculates the values of an array `ans` based on the proper es of the input strings `S`.
The code u lizes the `atcoder::z_algorithm` from the `atcoder/string` library, which is used to find the
longest common prefix of a string with each of its suffixes.

Here's a step-by-step explana on of the code:

1. Include the necessary C++ standard library (`<bits/stdc++.h>`) and the `atcoder/string` library.

2. Define the macro `rep(i,l,r)` as a shorthand for a for-loop with an increment of `1`. It iterates from
`l` (inclusive) to `r` (exclusive).

3. The `main()` func on starts here.

4. Read the integer `n` from the user, which represents the number of strings in the vector `S`.

5. Create a vector of strings `S` with size `n` to store the input strings.

6. Read the `n` strings and store them in the vector `S`.

7. Create an unordered map `memo` to store informa on about substrings of the strings in `S`. The key
is a substring, and the value is a vector containing the indices of strings in `S` that start with that
substring.

8. Loop through each string `S[i]` in `S`, and for each string, do the following:

a. Use the `atcoder::z_algorithm` func on to calculate the Z-func on of the string.

b. Find the smallest `j` such that the length of the string `S[i]` is divisible by `j`, and `Z[j]` (the Z-
func on value at index `j`) is equal to the length of the string `S[i]` minus `j`. This means that `S[i]`
repeats itself `j` mes in the string.

c. Update the `memo` map with the substring of `S[i]` from index 0 to `j - 1` as the key and add the
index `i` to the corresponding vector value.

9. Create a vector `ans` of size `n` to store the final answers for each string in `S`.
10. Loop through each key-value pair in the `memo` map, and for each key-value pair, do the following:

a. Create an unordered map `pre` to store the indices of the substrings in the `ans` array that have
already been used.

b. Create an unordered set `used` to store the values that have already been used as answers.

c. Ini alize the first index (0) in `used`.

d. For each index `i` in the vector `v` (values), do the following:

- Calculate the value `d` as the length of the string `S[i]` divided by the length of the key `k`.

- Check if the index `crr` (the poten al answer) exists in the `used` set. If it does, increment `crr`
by `d` un l an unused index is found.

- Update `pre` with the new `crr` value.

- Add `crr` to the `used` set to mark it as used.

- Set the answer for the string `S[i]` in the `ans` vector to be `crr` divided by `d`.

11. Output the values in the `ans` vector, separated by spaces.

12. End the program.

In summary, the code processes a vector of strings `S` and calculates the corresponding answers based
on certain proper es of the strings. It uses the `atcoder::z_algorithm` func on to determine repea ng
substrings and maps the answers to each string in the `ans` array. The final values of `ans` are then
output to the console.

Code:

#include<bits/stdc++.h>

#include<atcoder/string>

using namespace std;

#define rep(i,l,r)for(int i=(l);i<(r);i++)

int main(){

int n;

cin >> n;

vector<string>S(n);
rep(i,0,n)cin >> S[i];

unordered_map<string,vector<int>>memo;

rep(i,0,n){

auto ret=atcoder::z_algorithm(S[i]);

int len=S[i].size();

int ans=len;

rep(j,1,len)if(len%j==0&&ret[j]==len-j){

ans=j;

break;

memo[S[i].substr(0,ans)].push_back(i);

vector<int>ans(n);

for(auto[k,v]:memo){

unordered_map<int,int>pre;

unordered_set<int>used;

used.insert(0);

for(auto i:v){

int d=S[i].size()/k.size();

int crr=pre[d];

while(used.find(crr)!=used.end())crr+=d;

pre[d]=crr;

used.insert(crr);

ans[i]=crr/d;

rep(i,0,n){
if(i)cout << ' ';

cout << ans[i];

cout << endl;

}
THANK YOU
A DETAILED EDITORIAL FOR
ATCODER – ATCODER PROGRAMMING CONTEST 2023
SUMMER (ATCODER BEGINNER CONTEST 313)

Date of Contest: 05-08-2023

Editorial by
Dr. Dinesh Kumar Anguraj, Asso. Prof., Dept. of CSE.
Website Link: https://atcoder.jp/

Contest URL: https://atcoder.jp/contests/abc313

Mode: Rated & Unrated

Number of Contest Tasks: 7 Tasks

Number of Extra Tasks: 1 Task

Note & Credits: Problem statement and Hints from Atcoder.jp by the users
“en_translator (English) & physics (Japanese)”
CONTEST PROBLEM
STATEMENTS, HINTS AND
ALGORITHMS WITH CODE
A - To Be Saikyo  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 100 points

Problem Statement
There are N  people numbered 1 through N . Each person has a integer score called programming
ability; person i's programming ability is Pi  points. How many more points does person 1 need, so that

person 1 becomes the strongest? In other words, what is the minimum non-negative integer x such that 
P1 + x > Pi  for all i =
​ ​

 1?

Constraints
1 ≤ N ≤ 100
1 ≤ Pi ≤ 100 ​

All input values are integers.

Input
The input is given from Standard Input in the following format:

N
P1 P2 … PN
​ ​ ​

Output
Print the answer as an integer.

Sample Input 1  Copy

Copy
4
5 15 2 10

Sample Output 1  Copy

Copy
11

Person 1 becomes the strongest when their programming skill is 16 points or more, so the answer is 
16 − 5 = 11.
Sample Input 2  Copy

Copy
4
15 5 2 10

Sample Output 2  Copy

Copy
0

Person 1 is already the strongest, so no more programming skill is needed.

Sample Input 3  Copy

Copy
3
100 100 100

Sample Output 3  Copy

Copy
1
Algorithm:

Algorithm: Find the Strongest Person

1. Read the input value n, which represents the number of people.


2. Read the input list p containing the strength values of each person.
3. Initialize a variable m to 0. This variable will be used to find the maximum
strength among the other people (excluding the first person).
4. Iterate through the list p starting from the second person (index 1) up to the
last person (index n-1):
 Update m with the maximum value between m and the strength value of
the current person (p[i]).
5. After the loop, calculate the maximum strength value among the other people
as m.
6. Calculate the difference between the maximum strength among the others (m)
plus 1 and the strength of the first person (p[0]).
7. If the calculated difference is negative, set it to 0 to ensure it's a valid result.
8. Print the calculated result, which represents the minimum number of
additional strength points the first person needs to become the strongest
person.

Note: The algorithm assumes that the strength values are non-negative integers.

This algorithm effectively calculates the minimum strength difference needed for the
first person to become the strongest among the group, while ensuring that negative
differences are treated as 0.

Code:

n = int(input()) # Read the number of people

p = list(map(int, input().split())) # Read the strength values of each person

m = 0 # Ini alize maximum strength among others

# Find the maximum strength among the other people (excluding the first person)

for i in range(1, n):

m = max(m, p[i])

# Calculate the minimum addi onal strength needed for the first person to become the strongest

addi onal_strength = max(0, m + 1 - p[0])

print(addi onal_strength) # Print the result


B - Who is Saikyo?  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 300 points

Problem Statement
There are N  competitive programmers numbered person 1, person 2, …, and person N .
There is a relation called superiority between the programmers. For all pairs of distinct programmers (
person X , person Y ), exactly one of the following two relations holds: "person X  is stronger than
person Y " or "person Y  is stronger than person X ."
The superiority is transitive. In other words, for all triplets of distinct programmers (person X , person Y ,
person Z), it holds that:

if person X  is stronger than person Y  and person Y  is stronger than person Z , then person X  is
stronger than person Z .

A person X  is said to be the strongest programmer if person X  is stronger than person Y  for all
people Y  other than person X . (Under the constraints above, we can prove that there is always exactly
one such person.)

You have M  pieces of information on their superiority. The i-th of them is that "person Ai  is stronger

than person Bi ." ​

Can you determine the strongest programmer among the N  based on the information?
If you can, print the person's number. Otherwise, that is, if there are multiple possible strongest
programmers, print -1.

Constraints
2 ≤ N ≤ 50
0 ≤ M ≤ N (N2−1) ​

1 ≤ Ai , Bi ≤ N
​ ​

Ai 
​ = Bi ​

If i =
 j , then (Ai , Bi ) =

 (Aj , Bj ).
​ ​ ​

There is at least one way to determine superiorities for all pairs of distinct programmers, that is
consistent with the given information.

Input
The input is given from Standard Input in the following format:
N M
A1 B1
​ ​

A2 B2
​ ​


AM BM ​ ​

Output
If you can uniquely determine the strongest programmer, print the person's number; otherwise, print -1.

Sample Input 1  Copy

Copy
3 2
1 2
2 3

Sample Output 1  Copy

Copy
1

You have two pieces of information: "person 1 is stronger than person 2" and "person 2 is stronger than
person 3."
By the transitivity, you can also infer that "person 1 is stronger than person 3," so person 1 is the
strongest programmer.

Sample Input 2  Copy

Copy
3 2
1 3
2 3

Sample Output 2  Copy

Copy
-1

Both person 1 and person 2 may be the strongest programmer. Since you cannot uniquely determine
which is the strongest, you should print -1.

Sample Input 3  Copy


Copy
6 6
1 6
6 5
6 2
2 3
4 3
4 2

Sample Output 3  Copy

Copy
-1
Algorithm:

1. Read input values:


 Read the number of programmers N.
 Read the number of pairwise comparisons M.
 Initialize an array deg of size N to count the number of people stronger
than each programmer. Initialize all elements to 0.
2. Process comparisons:
 Loop M times to process each pairwise comparison.
 For each comparison, read the two programmers a and b being
compared (0-based indexing).
 Increment the deg value of programmer b by 1, indicating that there is
someone stronger than programmer b.
3. Find the strongest programmer:
 Initialize a variable ans to store the result. Set it to -1 initially.
 Loop through all programmers from 0 to N-1.
 Check if the deg value of programmer i is 0. If it is, then programmer i
is the strongest candidate based on the conditions provided.
 If ans is already assigned (not equal to -1), print -1 and exit
because there are two or more programmers with no one
stronger than them.
 Otherwise, set ans to i + 1 (adding 1 to convert from 0-based
indexing to 1-based indexing).
4. Output the result:
 If ans is still -1, there is no programmer with no one stronger than
them, so print -1.
 Otherwise, print the value of ans, which represents the strongest
programmer.

Complexity Analysis: The complexity of this algorithm is O(N + M), where N is the
number of programmers and M is the number of pairwise comparisons. This is
because you loop through all programmers once to calculate deg values, and then
loop through them again to find the strongest programmer. The array operations
and comparisons within the loops have constant time complexity.

Please note that this algorithm assumes the input data is correctly formatted and
follows the conditions described in the explanation you provided. If the input doesn't
adhere to these conditions, the algorithm might not produce correct results.

Code:

#include <bits/stdc++.h>

using namespace std;


int main() {

int N, M;

cin >> N >> M;

vector<int> deg(N, 0); // Ini#alize deg array with zeros

for (int i = 0; i < M; i++) {

int a, b;

cin >> a >> b;

deg[b - 1]++; // Increment the degree of programmer b (0-based indexing)

int ans = -1;

for (int i = 0; i < N; i++) {

if (deg[i] == 0) {

if (ans != -1) {

cout << -1 << endl;

return 0;

} else {

ans = i + 1; // Programmer i is a candidate for the strongest programmer

cout << ans << endl;

return 0;

}
C - Approximate Equalization 2  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 400 points

Problem Statement
You are given an integer sequence A = (A1 , A2 , … , AN ). You can perform the following operation any
​ ​ ​

number of times (possibly zero).

Choose integers i and j  with 1 ≤ i, j ≤ N . Decrease Ai  by one and increase Aj  by one.
​ ​

Find the minimum number of operations required to make the difference between the minimum and
maximum values of A at most one.

Constraints
1 ≤ N ≤ 2 × 105
1 ≤ Ai ≤ 109

All input values are integers.

Input
The input is given from Standard Input in the following format:

N
A1 A2 … AN
​ ​ ​

Output
Print the answer as an integer.

Sample Input 1  Copy

Copy
4
4 7 3 7

Sample Output 1  Copy

Copy
3
By the following three operations, the difference between the minimum and maximum values of A
 becomes at most one.

Choose i = 2 and j = 3 to make A = (4, 6, 4, 7).


Choose i = 4 and j = 1 to make A = (5, 6, 4, 6).
Choose i = 4 and j = 3 to make A = (5, 6, 5, 5).

You cannot make the difference between maximum and minimum values of A at most one by less than
three operations, so the answer is 3.

Sample Input 2  Copy

Copy
1
313

Sample Output 2  Copy

Copy
0

Sample Input 3  Copy

Copy
10
999999997 999999999 4 3 2 4 999999990 8 999999991 999999993

Sample Output 3  Copy

Copy
2499999974
Algorithm:

Step 1: Finding the Minimum Number of Operations to Equalize A and B

 Calculate the sum S of the absolute differences between corresponding


elements of sequences A and B.
 The minimum number of operations required to make A equal B is 2 * S.

Step 2: Finding B for Minimum Operations

 The sum of elements in B should equal the sum of elements in A.


 The maximum and minimum values of B should differ by at most one.
 Construct B by having (N - r) elements equal to p and r elements equal to (p
+ 1), where p is the quotient and r is the remainder when sum of elements of
A is divided by N.

Step 3: Minimizing the Difference Between A and B

 Sort array A in ascending order.


 Construct array B according to the pattern described in Step 2.
 Calculate the sum of absolute differences between corresponding elements of
A and B. Divide this sum by 2 and print it.

This algorithm guarantees the minimum number of operations needed to equalize A


and B while maintaining the constraints on B.

Code:

n = int(input())

a = list(map(int, input().split()))

sum_a = sum(a)

a.sort()

# Calculate the quo ent and remainder for construc ng B

p = sum_a // n

r = sum_a % n

# Construct B according to the pa ern

b = [p] * (n - r) + [p + 1] * r

# Calculate the sum of absolute differences and divide by 2

ans = sum(abs(ai - bi) for ai, bi in zip(a, b)) // 2

print(ans)
D - Odd or Even  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 550 points

Problem Statement
This is an interactive task (where your program and the judge interact via Standard Input and Output).

You are given an integer N  and an odd number K .


The judge has a hidden length-N  sequence A = (A1 , A2 , … , AN ) consisting of 0 and 1.
​ ​ ​

While you cannot directly access the elements of sequence A, you are allowed to ask the judge the
following query at most N  times.

Choose distinct integers x1 , x2 , …, and xK  between 1 and N , inclusive, to ask the parity of Ax1
​ ​ ​


​ +
A x2 + ⋯ + A xK .


Determine (A1 , A2 , … , AN ) by at most N  queries, and print the answer.


​ ​ ​

Here, the judge is adaptive. In other words, the judge may modify the contents of A as long as it is
consistent with the responses to the past queries.
Therefore, your program is considered correct if the output satisfies the following condition, and incorrect
otherwise:

your program prints a sequence consistent with the responses to the queries so far, and that is the
only such sequence.

Constraints
1 ≤ K < N ≤ 1000
K  is odd.
Ai  is 0 or 1.

Input and Output


This is an interactive task (where your program and the judge interact via Standard Input and Output).

First of all, receive N  and K  from Standard Input.

N K

Then, repeat asking queries until you can uniquely determine (A1 , A2 , … , AN ). ​ ​ ​

Each query should be printed to Standard Output in the following format, where x1 , x2 , …, and xK  are K
​ ​ ​

 distinct integers between 1 and N , inclusive.

? x1 x2 … xK
​ ​ ​
The response to the query is given from Standard Input in the following format.

Here, T  denotes the response to the query.

T  is 0 when Ax1 + Ax2 + ⋯ + AxK  is even, and





T  is 1 when Ax1 + Ax2 + ⋯ + AxK  is odd.





However, if x1 , x2 , … and xK  do not satisfy the constraints, or the number of queries exceeds N , then T
​ ​ ​

 is -1.

If the judge returns -1, your program is already considered incorrect, so terminate the program
immediately.

When you can determine all the elements of A, print those elements in the following format, and
terminate the program immediately.

! A1 A2 … AN
​ ​ ​

Notes
Print a newline and flush Standard Output at the end of each message. Otherwise, you may
get a  TLE  verdict.
The verdict will be indeterminate if there is malformed output during the interaction or your
program quits prematurely.
Terminate the program immediately after printing the answer, or the verdict will be indeterminate.
The judge for this problem is adaptive. This means that the judge may modify the contents of A as
long as it is consistent with the responses to the past queries.

Sample Interaction
In the following interaction, N = 5 and K = 3. Note that the following output itself will result
in  WA .
Here, A = (1, 0, 1, 1, 0) is indeed consistent with the responses, but so is (0, 0, 1, 0, 0), so sequence A
 is not uniquely determined. Thus, this program is considered incorrect.

Input Output Description

5 3 First, you are given integers N  and K .

? 2 4 1 You ask a query with (x1 , x2 , x3 )


​ ​ ​ = (2, 4, 1).
0 The response to the query is 0, so the judge returns that value.

? 5 3 2 You ask a query with (x1 , x2 , x3 )


​ ​ ​ = (5, 3, 2).
1 The response to the query is 1, so the judge returns that value.
Input Output Description

! 1 0 1 1 You print (1, 0, 1, 1, 0) to guess A. Since sequence A is not


0
uniquely determined, the verdict will be  WA .
Algorithm:

1. Initialization:
 Read input values N (size of the array) and K.
 Define a function send that sends queries and receives responses. The
function increments the input vector elements by 1 before sending the
query and returns the response.
 Initialize an array ans to store the final results.
2. Solving for N=K+1:
 Perform K+1 queries to determine the initial K+1 values of the array.
 Calculate the XOR of these initial values, which is used to determine the
parity of the remaining value.
3. Solving for N > K+1:
 Iterate over the array indices from K+2 to N, and for each index i, send
a query for the subarray (1, 2, ..., K-1, i).
 Use the responses and the previously determined values to calculate
the value of A[i] based on XOR operations.
4. Output the Result:
 Print the resulting array ans as the final solution to the problem.

The algorithm uses XOR operations and a set of well-constructed queries to


determine the values of the array elements. The key idea is to use the parity of the
initial elements to determine the remaining values, making use of the XOR property.
The algorithm aims to solve the problem in a minimum number of queries.

Code:

#include <bits/stdc++.h>

using namespace std;

void out(vector<int> v) {

for (unsigned i = 0; i < v.size(); i++) {

cout << v[i] << " \n"[i + 1 == v.size()];

}
}

int main() {

int N, K;

cin >> N >> K;

auto send = [&](vector<int> v) {

for (auto& x : v) x++;

cout << "? ", out(v);

cout.flush();

int x;

cin >> x;

return x;

};

vector<int> ans(N);

int r = 0;

for (int i = 0; i < K + 1; i++) {

vector<int> v;

for (int j = 0; j < K + 1; j++)

if (i != j) v.push_back(j);

ans[i] = send(v);

r ^= ans[i];

for (int i = 0; i < K + 1; i++) ans[i] ^= r;

vector<int> v(K);

int s = 0;

for (int i = 0; i < K - 1; i++) v[i] = i, s ^= ans[i];

for (int i = K + 1; i < N; i++) {

v.back() = i;

int t = send(v);
ans[i] = s ^ t;

cout << "! ", out(ans);

cout.flush();

}
E - Duplicate  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 600 points

Problem Statement
For a string S  consisting of digits from 1 through 9, let f (S) be the string T  obtained by the following
procedure. (Si  denotes the i-th character of S .)

Let T  be an initially empty string.


For i = 1, 2, … , ∣S∣ − 1, perform the following operation:
Append n copies of Si  to the tail of T , where n is the value when Si+1  is interpreted as an
​ ​

integer.

For example, S = 313 yields f (S) = 3111 by the following steps.


T  is initially empty.
For i = 1, we have n = 1. Append one copy of 3 to T , which becomes 3.
For i = 2, we have n = 3. Append three copies of 1 to T , which becomes 3111.
Terminate the procedure. We obtain T = 3111.

You are given a length-N  string S  consisting of digits from 1 through 9.


You repeat the following operation until the length of S  becomes 1: replace S  with f (S).
Find how many times, modulo 998244353, you perform the operation until you complete it. If you will
repeat the operation indefinitely, print -1 instead.

Constraints
2 ≤ N ≤ 106
S  is a length-N  string consisting of 1, 2, 3, 4, 5, 6, 7, 8, and 9.

Input
The input is given from Standard Input in the following format:

N
S

Output
Print the number of times, modulo 998244353, that you perform the operation until you complete it. If
you will repeat the operation indefinitely, print -1 instead.
Sample Input 1  Copy

Copy
3
313

Sample Output 1  Copy

Copy
4

If S = 313, the length of S  be comes 1 after four operations.


We have f (S) = 3111. Replace S  with 3111.
We have f (S) = 311. Replace S  with 311.
We have f (S) = 31. Replace S  with 31.
We have f (S) = 3. Replace S  with 3.
Now that the length of S  is 1, terminate the repetition.

Sample Input 2  Copy

Copy
9
123456789

Sample Output 2  Copy

Copy
-1

If S = 123456789, you indefinitely repeat the operation. In this case, -1 should be printed.

Sample Input 3  Copy

Copy
2
11

Sample Output 3  Copy

Copy
1
Algorithm:

1. Run-Length Encoding (RLE): The code begins by defining a function


RunLengthEncoding that takes a string S and returns a run-length encoded
representation of it. This encoding represents consecutive occurrences of the
same character in S as a pair of the character and the count of occurrences.
This is used to simplify the manipulation of repeated characters in the string.
2. Handling Invalid Cases: The code checks for the presence of adjacent digits
greater than or equal to '2' in the input string S. If such adjacent digits exist,
the code immediately outputs "-1" as the answer, indicating that the
transformation is not possible.
3. Iterating Through the RLE Representation: The code performs operations
on the run-length encoded string representation. It iterates through the RLE
representation in reverse order (from the end of the string to the beginning).
4. Transformation Operations: The code simulates the transformation of the
string S by applying specific operations based on the characteristics of the
run-length encoded representation. The transformation rules are as follows:
 If the current character in the RLE representation is '1', it represents a
sequence of consecutive '1's. The code updates the total number of
operations based on the length of this sequence and the preceding
digit.
 If the current character is not '1' (i.e., it is in the range '2' to '9'), the
code performs a single operation.
5. Output the Result: The final result is the computed number of operations
required to transform the string S. The code outputs this result.

Code:

#include <bits/stdc++.h>

using namespace std;

#include "atcoder/modint.hpp"

using mint = atcoder::modint998244353;

vector<pair<char, int>> RunLengthEncoding(string& S) {


if (S.empty()) return {};

vector<pair<char, int>> ret;

char c = S[0];

int n = 1;

for (int i = 1; i < (int)S.size(); i++) {

if (S[i] == c)

n++;

else {

ret.emplace_back(c, n);

c = S[i], n = 1;

ret.emplace_back(c, n);

return ret;

int main() {

int N;

string S;

cin >> N >> S;

for (int i = 0; i + 1 < N; i++) {

if (S[i] >= '2' and S[i + 1] >= '2') {

cout << "-1\n";

exit(0);

auto rle = RunLengthEncoding(S);

mint t = 0;

char last = '1';

while (!rle.empty()) {

char c;
mint n;

>e(c, n) = rle.back();

rle.pop_back();

if (c == '1') {

n += t * (last - '1');

t += n;

} else {

t += 1;

last = c;

cout << (t - 1).val() << "\n";

Sdf

Sdfsd

Sedfs

Dfsd

Sdfsd

}
F - Flip Machines  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 625 points

Problem Statement
There are N  cards numbered 1 through N . Each face of a card has an integer written on it; card i has 
Ai  on its front and Bi  on its back. Initially, all cards are face up.
​ ​

There are M  machines numbered 1 through M . Machine j  has two (not necessarily distinct) integers Xj ​

 and Yj  between 1 and N . If you power up machine j , it flips card Xj  with the probability of  12 , and flips
​ ​ ​

card Yj  with the remaining probability of  12 . This probability is independent for each power-up.
​ ​

Snuke will perform the following procedure.

1. Choose a set S  consisting of integers from 1 through M .


2. For each element in S  in ascending order, power up the machine with that number.

Among Snuke's possible choices of S , find the maximum expected value of the sum of the integers
written on the face-up sides of the cards after the procedure.

Constraints
1 ≤ N ≤ 40
1 ≤ M ≤ 105
1 ≤ Ai , Bi ≤ 104 ​ ​

1 ≤ Xj , Y j ≤ N ​ ​

All input values are integers.

Input
The input is given from Standard Input in the following format:

N M
A1 B1
​ ​


AN BN ​ ​

X1 Y 1
​ ​


XM Y M ​ ​
Output
Print the answer. Your output is considered correct if the absolute or relative difference from the true
value is at most 10−6 .

Sample Input 1  Copy

Copy
3 1
3 10
10 6
5 2
1 2

Sample Output 1  Copy

Copy
19.500000

If S  is chosen to be an empty set, no machine is powered up, so the expected sum of the integers
written on the face-up sides of the cards after the procedure is 3 + 10 + 5 = 18.
If S  is chosen to be {1}, machine 1 is powered up.

If card X1 = 1 is flipped, the expected sum of the integers written on the face-up sides of the cards

after the procedure is 10 + 10 + 5 = 25.


If card Y1 = 2 is flipped, the expected sum of the integers written on the face-up sides of the cards

after the procedure is 3 + 6 + 5 = 14.

Thus, the expected value is  25+14


2

= 19.5.
Therefore, the maximum expected value of the sum of the integers written on the face-up sides of the
cards after the procedure is 19.5.

Sample Input 2  Copy

Copy
1 3
5 100
1 1
1 1
1 1

Sample Output 2  Copy

Copy
100.000000

Different machines may have the same (Xj , Yj ). ​ ​


Sample Input 3  Copy

Copy
8 10
6918 9211
16 1868
3857 8537
3340 8506
6263 7940
1449 4593
5902 1932
310 6991
4 4
8 6
3 5
1 1
4 2
5 6
7 5
3 3
1 5
3 1

Sample Output 3  Copy

Copy
45945.000000
Algorithm:

This problem involves a sequence of machines, each with two sides, and the goal is
to determine the expected sum of integers on the face-up sides of the cards after
applying specific operations. The editorial provides insights into the problem,
explains the key observations, and presents two algorithms to solve it. Here's an
overview of the main ideas:

1. Expected Value Calculation: The first part of the editorial discusses how to
calculate the expected value of integers written on the face-up sides of the
cards after the operations are completed. It considers the case where
machines have equal values for their two sides first and provides a simple
formula for the probability that a card ends up being face down.
2. Problem Transformation: The original problem is then transformed into a
more manageable form. The goal is to maximize a value W by choosing a
subset of machines, where the value W is based on the given constraints and
the difference between the values on the face-up and face-down sides of the
cards.
3. Algorithms to Solve the Problem: The editorial presents two algorithms to
solve the problem:
 Algorithm 1 (Brute Force): This algorithm tries all possible sets of
indices I∩P and calculates the optimal choice of machines for each set.
It utilizes the observation that machines with Xj∈P and Yj∈P are always
unused.
 Algorithm 2 (Bit DP): This algorithm uses dynamic programming (DP)
with a bit mask approach to efficiently explore the possibilities. It
maintains a DP table dp[i][S], where i represents the number of
machines chosen from P, and S is a bitmask indicating which machines
from Q have been chosen.
The choice of which algorithm to use depends on the relative sizes of the sets
P and Q.
4. Sample C++ Implementation: The provided C++ code is a full
implementation of the problem solution using the concepts explained in the
editorial. It reads input, processes the machines and their values, and
calculates the expected value based on the chosen algorithm.

Overall, the code efficiently solves the problem by leveraging expected value
calculations and choosing the appropriate algorithm based on the characteristics of
the input. The complexity of the solution is within the constraints of the problem,
making it suitable for larger inputs.
Code:

#include<bits/stdc++.h>

using namespace std;

using ll = long long;

int main() {

int n, m;

cin >> n >> m;

vector<int> a(n), b(n);

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

cin >> a[i] >> b[i];

vector<int> x(m), y(m);

for (int i = 0; i < m; i++) {

cin >> x[i] >> y[i];

--x[i], --y[i];

if (x[i] == y[i] and a[x[i]] < b[x[i]]) swap(a[x[i]], b[x[i]]);

int ans = 0;

vector<int> p, q;

vector<int> id(n);

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

ans += a[i] * 2;

int d = abs(a[i] - b[i]);

if (a[i] >= b[i]) {

id[i] = p.size();
p.push_back(d);

} else {

id[i] = q.size();

q.push_back(d);

int ps = p.size(), qs = q.size();

vector<ll> ls(ps);

for (int i = 0; i < m; i++) {

bool xp = (a[x[i]] >= b[x[i]]);

bool yp = (a[y[i]] >= b[y[i]]);

if (xp == yp) {

if (!xp) {

ans += q[id[x[i]]] + q[id[y[i]]];

q[id[x[i]]] = q[id[y[i]]] = 0;

} else {

if (!xp) swap(x[i], y[i]);

ls[id[x[i]]] |= 1LL << id[y[i]];

if (ps <= qs) {

int mx = 0;

for (int bit = 0; bit < (1 << ps); bit++) {

int now = 0;

ll cq = 0;

for (int i = 0; i < ps; i++) {

if (bit >> i & 1) {

now -= p[i];

cq |= ls[i];

}
}

for (int i = 0; i < qs; i++) {

if (cq >> i & 1) now += q[i];

mx = max(mx, now);

ans += mx;

} else {

vector dp(ps + 1, vector<int>(1 << qs, -1e9));

dp[0][0] = 0;

for (int i = 0; i < ps; i++) {

for (int j = 0; j < (1 << qs); j++) {

dp[i + 1][j] = max(dp[i + 1][j], dp[i][j]);

dp[i + 1][j | ls[i]] = max(dp[i + 1][j | ls[i]], dp[i][j] - p[i]);

int mx = 0;

for (int j = 0; j < (1 << qs); j++) {

int now = dp[ps][j];

for (int i = 0; i < qs; i++) {

if (j >> i & 1) now += q[i];

mx = max(mx, now);

ans += mx;

cout << fixed << ans / 2. << endl;

}
G - Redistribution of Piles  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 625 points

Problem Statement
There are N  plates numbered 1 through N . Dish i has ai  stones on it. There is also an empty bag.

You can perform the following two kinds of operations any number of times (possibly zero) in any order.

Remove one stone from each plate with one or more stones. Put the removed stones into the bag.
Take N  stones out of the bag, and put one stone to each plate. This operation can be performed
only when the bag has N  or more stones.

Let bi  be the number of stones on plate i after you finished the operations. Print the number, modulo 

998244353, of sequences of integers (b1 , b2 , … , bN ) of length N  that can result from the operations.
​ ​ ​

Constraints
1 ≤ N ≤ 2 × 105
0 ≤ ai ≤ 109​

Input
The input is given from Standard Input in the following format:

N
a1 a2 … aN
​ ​ ​

Output
Print the number, modulo 998244353, of possible sequences (b1 , b2 , … , bN ).
​ ​ ​

Sample Input 1  Copy

Copy
3
3 1 3

Sample Output 1  Copy

Copy
7
For example, b becomes (2, 1, 2) by the following procedure.

Perform the first operation. b becomes (2, 0, 2).


Perform the first operation. b becomes (1, 0, 1).
Perform the second operation. b becomes (2, 1, 2).

The following seven sequences can be the resulting b.

(0, 0, 0)
(1, 0, 1)
(1, 1, 1)
(2, 0, 2)
(2, 1, 2)
(2, 2, 2)
(3, 1, 3)

Sample Input 2  Copy

Copy
1
0

Sample Output 2  Copy

Copy
1

There are one sequence, (0), that can be the resulting b.

Sample Input 3  Copy

Copy
5
1 3 5 7 9

Sample Output 3  Copy

Copy
36

Sample Input 4  Copy

Copy
10
766294629 440423913 59187619 725560240 585990756 965580535 623321125 550925213 122410708 549392044
Sample Output 4  Copy

Copy
666174028
Algorithm:

The provided C++ code solves a problem involving two types of operations, A and B,
applied to a sequence of dishes with stones. The goal is to count the number of valid
sequences of operations that satisfy specific conditions. Here's an overview of the
key observations and the algorithm used to solve the problem:

1. Key Observations: The code makes two important observations that help
simplify the problem:
 Operation A is never performed right after operation B.
 Operation B is never performed right after taking stones from all the
dishes in an operation A.
2. Problem Transformation: The problem is transformed into counting
appropriate sequences of operations, represented as pairs of integers (x, y),
where x indicates the number of times operation A is performed, and y
indicates the number of times operation B is performed.
3. Expression for Counting Sequences: For a fixed value of x, the valid range of
y and the count of valid sequences are determined based on the following
conditions:
 If x is less than or equal to the minimum frequency of operation A, y
must be 0 (one candidate). Performing operation B would violate the
second condition.
 If the minimum frequency of operation A is less than x, then 0 ≤ y ≤
⌊s/N⌋, where s is the total number of stones in the dishes (⌊s/N⌋+1
candidates).
4. Floor Sum Algorithm: The problem's count of valid sequences is expressed
as a sum of floor values. The code uses the floor sum algorithm, which
computes these sums efficiently. The AtCoder Library's floor sum function is
utilized for this purpose.
5. Sample C++ Implementation: The provided C++ code reads input, sorts the
given sequence of frequencies of operation A, and then iterates through the
sorted sequence to compute the count of valid sequences of operations. The
algorithm leverages the floor sum function from the AtCoder Library to
calculate these sums efficiently.

Overall, the code demonstrates an approach to efficiently solve the problem using
key observations, transformation, and the floor sum algorithm. The complexity of the
solution is suitable for the given constraints, ensuring a fast and efficient solution.
Code:

#include <bits/stdc++.h>

using namespace std;

#include "atcoder/math.hpp"

#include "atcoder/modint.hpp"

using mint = atcoder::modint998244353;

using ll = long long;

int main() {

ll N;

cin >> N;

vector<ll> A(N);

for(auto&x : A) cin >> x;

sort(begin(A), end(A));

ll s = A[0] * N;

mint ans = A[0] + 1;

for (int i = 1; i < N; i++) {

ll L = A[i - 1];

ll R = A[i];

ll a = N - i;

ll b = s - L * (N - i);

ll m = N;

ll cur = 0;

cur += atcoder::floor_sum(R + 1, m, a, b);

cur -= atcoder::floor_sum(L + 1, m, a, b);

cur += R - L;

ans += cur;

s += (R - L) * (N - i);

}
cout << ans.val() << "\n";

}
Ex - Group Photo  Editorial
 / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 650 points

Problem Statement
(2N + 1) people are forming two rows to take a group photograph. There are N  people in the front row;
the i-th of them has a height of Ai . There are (N + 1) people in the back row; the i-th of them has a

height of Bi . It is guaranteed that the heights of the (2N + 1) people are distinct. Within each row, we

can freely rearrange the people.

Suppose that the heights of the people in the front row are a1 , a2 , … , aN  from the left, and those in the
​ ​ ​

back row are b1 , b2 , … , bN +1  from the left. This arrangement is said to be good if all of the following
​ ​ ​

conditions are satisfied:

ai < bi  or ai−1 < bi  for all i (2 ≤ i ≤ N ).


​ ​ ​ ​

a1 < b1 . ​ ​

aN < bN +1 . ​ ​

Among the N ! ways to rearrange the front row, how many of them, modulo 998244353, are such ways
that we can rearrange the back row to make the arrangement good?

Constraints
1 ≤ N ≤ 5000
1 ≤ Ai , Bi ≤ 109 ​ ​

Ai =
 Aj  (1 ≤ i < j ≤ N )
​ ​

Bi =
 Bj  (1 ≤ i < j ≤ N + 1)
​ ​

Ai =
 Bj  (1 ≤ i ≤ N , 1 ≤ j ≤ N + 1)
​ ​

All input values are integers.

Input
The input is given from Standard Input in the following format:

N
A1 A2 … AN
​ ​ ​

B1 B2 … BN +1
​ ​ ​

Output
Print the answer as an integer.
Sample Input 1  Copy

Copy
3
1 12 6
4 3 10 9

Sample Output 1  Copy

Copy
2

When a = (1, 12, 6), we can let, for example, b = (4, 3, 10, 9) to make the arrangement good.
When a = (6, 12, 1), we can let, for example, b = (10, 9, 4, 3) to make the arrangement good.
When a is one of the other four ways, no rearrangement of the back row (that is, none of the
possible 24 candidates of b) makes the arrangement good.

Thus, the answer is 2.

Sample Input 2  Copy

Copy
1
5
1 10

Sample Output 2  Copy

Copy
0

Sample Input 3  Copy

Copy
10
189330739 910286918 802329211 923078537 492686568 404539679 822804784 303238506 650287940 1
125660016 430302156 982631932 773361868 161735902 731963982 317063340 880895728 1000000000 707723857 4

Sample Output 3  Copy

Copy
3542400
Algorithm:

The provided C++ code solves a specific problem that involves counting good
arrangements of elements from two sequences, A and B, while satisfying certain
conditions. Here's a step-by-step explanation of the code:

1. Input:
 Reads the value of n, the number of elements in the sequences A and
B.
 Reads the elements of sequence A.
 Reads the elements of sequence B (with an extra element to
accommodate the index shift when checking conditions).
2. Sorting:
 Sorts both sequences A and B in ascending order.
3. Dynamic Programming (DP) Approach:
 The code uses a 2D DP table dp with dimensions (n+1) x (n+1) to
keep track of the number of good arrangements.
 Initializes dp[0][0] to 1, representing the base case where no elements
from A or B are used.
4. Iterative DP:
 Loops through the elements of sequence A (indexed by i) to determine
the relative ordering between elements in A and elements in B.
 For each element in A (A[i]), the code iterates through possible
numbers of connected components (indexed by j), where j represents
the number of elements in B that are less than or equal to A[i].
 For each combination of i and j, the code considers three patterns
(indexed by p):
 Pattern 0: A[i] forms a new independent connected component.
 Pattern 1: A[i] sticks onto the left or right of an existing
connected component.
 Pattern 2: A[i] glues two existing connected components to
reduce the number of connected components by one.
 The code checks conditions to ensure that the elements from B are
greater than the elements from A, and updates the DP table
accordingly.
5. Output:
 The code outputs the result, which corresponds to the value dp[n][1],
representing the number of good arrangements that satisfy the
conditions.
6. Modular Arithmetic:
 The code uses modint998244353 from the AtCoder Library, which is a
modular integer type that ensures operations are performed modulo
998244353. This is commonly used in competitive programming to
avoid integer overflow and efficiently compute results modulo a prime
number.

Overall, the code uses dynamic programming to efficiently count good arrangements
while satisfying specific conditions. The approach is based on the relative ordering
between elements in sequences A and B, and the DP table tracks the number of valid
arrangements.

Code:

#include<bits/stdc++.h>

#include<atcoder/modint>

using namespace std;

using namespace atcoder;

using mint = modint998244353;

int main() {

int n;

cin >> n;

vector<int> a(n), b(n + 1);

for (int &i: a) cin >> i;

for (int &i: b) cin >> i;

sort(a.begin(), a.end());

sort(b.begin(), b.end());

vector dp(n + 1, vector<mint>(n + 1));

dp[0][0] = 1;

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


for (int j = 0; j <= i; j++) {

for (int p = 0; p < 3; p++) {

if (p > j) break;

if (i + j + 2 - p > n + 1) con0nue;

if (p <= 1 and b[i + j] < a[i]) con0nue;

mint coef;

if (p == 0) coef = j + 1;

else if (p == 1) coef = 2 * j;

else coef = j - 1;

dp[i + 1][j + 1 - p] += dp[i][j] * coef;

cout << dp[n][1].val() << endl;

}
THANK YOU
A DETAILED EDITORIAL FOR
ATCODER – ATCODER PROGRAMMING CONTEST 2023
SUMMER (ATCODER BEGINNER CONTEST 314)

Date of Contest: 12-08-2023

Editorial by
Dr. Dinesh Kumar Anguraj, Asso. Prof., Dept. of CSE.
Website Link: https://atcoder.jp/

Contest URL: https://atcoder.jp/contests/abc314

Mode: Rated & Unrated

Number of Contest Tasks: 7 Tasks

Number of Extra Tasks: 1 Task

Note & Credits: Problem statement and Hints from Atcoder.jp by the users
“en_translator (English) & physics (Japanese)”
CONTEST PROBLEM
STATEMENTS, HINTS AND
ALGORITHMS WITH CODE
A - 3.14  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 100 points

Problem Statement
The number pi to the 100-th decimal place is

3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679.

You are given an integer N  between 1 and 100, inclusive.

Print the value of pi to the N -th decimal place.

More precisely, truncate the value of pi to N  decimal places and print the result without removing the
trailing 0s.

Constraints
1 ≤ N ≤ 100
N  is an integer.

Input
The input is given from Standard Input in the following format:

Output
Print the value of pi to the N -th decimal place in a single line.

Sample Input 1  Copy

Copy
2

Sample Output 1  Copy

Copy
3.14

Truncating the value of pi to 2 decimal places results in 3.14. Thus, you should print 3.14.
Sample Input 2  Copy

Copy
32

Sample Output 2  Copy

Copy
3.14159265358979323846264338327950

Do not remove the trailing 0s.

Sample Input 3  Copy

Copy
100

Sample Output 3  Copy

Copy
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
Algorithm:

Step 1: Start

Step 2: Read the value of N (the number of characters to print).

Step 3: Ini alize a string variable pi with the constant string "3.14".

Step 4: Ini alize a variable i to 0 (the loop counter).

Step 5: While i is less than or equal to N+1, go to Step 6. Otherwise, go to Step 8.

Step 6: Print the character at the i-th index of the string pi.

Step 7: Increment the value of i by 1, then go back to Step 5.

Step 8: Print a newline character to separate the output.

Step 9: End

Code:

#include <string>

#include <iostream>

using namespace std;

int main() {

string pi =
"3.141592653589793238462643383279502884197169399375105820974944592307816406286208
9986280348253421170679";

int N;

cin >> N;

for (int i = 0; i < N + 2; ++i) // Print the first N+2 characters

cout << pi[i];

cout << endl;

return 0;

}
B - Roulette  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 200 points

Problem Statement
N  people, person 1, person 2, …, person N , are playing roulette. The outcome of a spin is one of the 
37 integers from 0 to 36. For each i = 1, 2, … , N , person i has bet on Ci  of the 37 possible ​

outcomes: Ai,1 , Ai,2 , … , Ai,Ci . ​ ​


The wheel has been spun, and the outcome is X . Print the numbers of all people who have bet on X
 with the fewest bets, in ascending order.

More formally, print all integers i between 1 and N , inclusive, that satisfy both of the following
conditions, in ascending order:

Person i has bet on X .


For each j = 1, 2, … , N , if person j  has bet on X , then Ci ​
≤ Cj .

Note that there may be no number to print (see Sample Input 2).

Constraints
1 ≤ N ≤ 100
1 ≤ Ci ≤ 37 ​

0 ≤ Ai,j ≤ 36 ​

Ai,1 , Ai,2 , … , Ai,Ci  are all different for each i = 1, 2, … , N .


​ ​


0 ≤ X ≤ 36
All input values are integers.

Input
The input is given from Standard Input in the following format:

N
C1 ​

A1,1 A1,2 … A1,C1


​ ​


C2 ​

A2,1 A2,2 … A2,C2


​ ​



CN ​

AN ,1 AN ,2 … AN ,CN
​ ​


X
Output
Let B1 , B2 , … , BK  be the sequence of numbers to be printed in ascending order. Using the following
​ ​ ​

format, print the count of numbers to be printed, K , on the first line, and B1 , B2 , … , BK  separated by
​ ​ ​

spaces on the second line:

K
B1 B2 … BK
​ ​ ​

Sample Input 1  Copy

Copy
4
3
7 19 20
4
4 19 24 0
2
26 10
3
19 31 24
19

Sample Output 1  Copy

Copy
2
1 4

The wheel has been spun, and the outcome is 19. The people who has bet on 19 are person 1, person 
2, and person 4, and the number of their bets are 3, 4, and 3, respectively. Therefore, among the people
who has bet on 19, the ones with the fewest bets are person 1 and person 4.

Sample Input 2  Copy

Copy
3
1
1
1
2
1
3
0

Sample Output 2  Copy

Copy
0
The wheel has been spun and the outcome is 0, but no one has bet on 0, so there is no number to print.
Algorithm:

Step 1: Start

Step 2: Receive the input values.

a. Read the number of people, n.

b. Read the bet value, x.

c. For each person i from 1 to n, read the number of bets they made, c[i], and store the bets
in an array a[i].

Step 3: Create a variable-length array vec.

a. For each person i from 1 to n, if they bet on the value x, add i to vec.

Step 4: Find the minimum value Cmin among the number of bets made by the people in vec.

Step 5: Create another variable-length array ans.

a. For each person i in vec, if they made the minimum number of bets (c[i] == Cmin), add i to
ans.

Step 6: Print the size of ans.

Step 7: Print the elements in ans in ascending order.

Code:

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

int main(void)

int n, x, c[101];

vector<int> a[101];

cin >> n;

for(int i = 1; i <= n; i++){

cin >> c[i];

a[i].resize(c[i]);

for(int j = 0; j < c[i]; j++) cin >> a[i][j];

}
cin >> x;

vector<int> vec;

for(int i = 1; i <= n; i++){

for(int j = 0; j < c[i]; j++) if(a[i][j] == x) vec.push_back(i);

int cmin = 37;

for(auto i : vec) cmin = min(cmin, c[i]);

vector<int> ans;

for(auto i : vec) if(c[i] == cmin) ans.push_back(i);

cout << ans.size() << endl;

for(auto b : ans) cout << b << " ";

cout << endl;

return 0;

}
C - Rotate Colored Subsequence  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 300 points

Problem Statement
You are given a string S  of length N  consisting of lowercase English letters. Each character of S  is
painted in one of the M  colors: color 1, color 2, ..., color M ; for each i = 1, 2, … , N , the i-th character
of S  is painted in color Ci . ​

For each i = 1, 2, … , M  in this order, let us perform the following operation.
Perform a right circular shift by 1 on the part of S  painted in color i. That is, if the p1 -th, p2 -th, p3 -
​ ​ ​

th, …, pk -th characters are painted in color i from left to right, then simultaneously replace the p1 -
​ ​

th, p2 -th, p3 -th, …, pk -th characters of S  with the pk -th, p1 -th, p2 -th, …, pk−1 -th characters of S ,
​ ​ ​ ​ ​ ​ ​

respectively.

Print the final S  after the above operations.

The constraints guarantee that at least one character of S  is painted in each of the M  colors.

Constraints
1 ≤ M ≤ N ≤ 2 × 105
1 ≤ Ci ≤ M ​

N , M , and Ci  are all integers.


S  is a string of length N  consisting of lowercase English letters.


For each integer 1 ≤ i ≤ M , there is an integer 1 ≤ j ≤ N  such that Cj = i. ​

Input
The input is given from Standard Input in the following format:

N M
S
C1 C2 … CN
​ ​ ​

Output
Print the answer.

Sample Input 1  Copy


Copy
8 3
apzbqrcs
1 2 3 1 2 2 1 2

Sample Output 1  Copy

Copy
cszapqbr

Initially, S = apzbqrcs.
For i = 1, perform a right circular shift by 1 on the part of S  formed by the 1-st, 4-th, 7-th
characters, resulting in S = cpzaqrbs.
For i = 2, perform a right circular shift by 1 on the part of S  formed by the 2-nd, 5-th, 6-th, 8-th
characters, resulting in S = cszapqbr.
For i = 3, perform a right circular shift by 1 on the part of S  formed by the 3-rd character, resulting
in S = cszapqbr (here, S  is not changed).

Thus, you should print cszapqbr, the final S .

Sample Input 2  Copy

Copy
2 1
aa
1 1

Sample Output 2  Copy

Copy
aa
Algorithm:

Step 1: Start

Step 2: Read the input values.

a. Read the length of the string, n, and the number of colors, m.

b. Read the string, s.

c. For each index i from 0 to n-1, read the color value, c[i], and store the posi"on i in the
variable-length array p corresponding to color c[i].

Step 3: Ini"alize a string t of length n with all characters set to '?'.

Step 4: For each color i from 1 to m, do the following:

a. Get the size k of the array p[i] (posi"ons for color i).

b. Rotate the characters in the string s based on the posi"ons in p[i].

- Set the character at posi"on p[i][(j+1)%k] in the string t to be the character at


posi"on p[i][j] in the string s, for each j from 0 to k-1.

Step 5: Print the string t as the final result.

Step 6: End

Code:

#include <iostream>

#include <vector>

using namespace std;

int n, m;

string s;

int c[200000];

vector<int> p[200001];

int main(void)

cin >> n >> m;

cin >> s;

for(int i = 0; i < n; i++) cin >> c[i];

for(int i = 0; i < n; i++) p[c[i]].push_back(i);


string t(n, '?');

for(int i = 1; i <= m; i++){

int k = p[i].size();

for(int j = 0; j < k; j++) t[p[i][(j+1)%k]] = s[p[i][j]];

cout << t << endl;

return 0;

}
D - LOWER  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 400 points

Problem Statement
You are given a string S  of length N  consisting of uppercase and lowercase English letters.

Let us perform Q operations on the string S . The i-th operation (1 ≤ i ≤ Q) is represented by a tuple 


(ti , xi , ci ) of two integers and one character, as follows.
​ ​ ​

If ti ​ = 1, change the xi -th character of S  to ci .


​ ​

If ti ​ = 2, convert all uppercase letters in S  to lowercase (do not use xi , ci  for this operation).
​ ​

If ti ​ = 3, convert all lowercase letters in S  to uppercase (do not use xi , ci  for this operation).
​ ​

Print the S  after the Q operations.

Constraints
1 ≤ N ≤ 5 × 105
S  is a string of length N  consisting of uppercase and lowercase English letters.
1 ≤ Q ≤ 5 × 105
1 ≤ ti ≤ 3 (1 ≤ i ≤ Q) ​

If ti = 1, then 1 ≤ xi ≤ N  (1 ≤ i ≤ Q).


​ ​

ci  is an uppercase or lowercase English letter.


If ti =
 1, then xi = 0 and ci = 'a'.
​ ​ ​

N , Q, ti , xi  are all integers.


​ ​

Input
The input is given from Standard Input in the following format:

N
S
Q
t 1 x1 c1
​ ​ ​

t 2 x2 c2
​ ​ ​


t Q xQ cQ​ ​ ​

Output
Print the answer in a single line.
Sample Input 1  Copy

Copy
7
AtCoder
5
1 4 i
3 0 a
1 5 b
2 0 a
1 4 Y

Sample Output 1  Copy

Copy
atcYber

Initially, the string S  is AtCoder.

The first operation changes the 4-th character to i, changing S  to AtCider.


The second operation converts all lowercase letters to uppercase, changing S  to ATCIDER.
The third operation changes the 5-th character to b, changing S  to ATCIbER.
The fourth operation converts all uppercase letters to lowercase, changing S  to atciber.
The fifth operation changes the 4-th character to Y, changing S  to atcYber.

After the operations, the string S  is atcYber, so print atcYber.

Sample Input 2  Copy

Copy
35
TheQuickBrownFoxJumpsOverTheLazyDog
10
2 0 a
1 19 G
1 13 m
1 2 E
1 21 F
2 0 a
1 27 b
3 0 a
3 0 a
1 15 i

Sample Output 2  Copy

Copy
TEEQUICKBROWMFiXJUGPFOVERTBELAZYDOG
Algorithm:

Step 1: Start

Step 2: Read the input values.

a. Read the length of the string, N, and the string itself, S.

b. Ini alize a vector status to store the status of each character in the string. Each element is a
pair of (last update me, current character).

c. Set the ini al me for all characters in status to 0.

d. Read the number of opera ons, Q.

Step 3: Iterate through each opera on:

a. Read the me, index, and character for the opera on.

b. If the opera on is an individual opera on (t == 1), update the status for the character at
index (x-1) in the vector status.

c. If the opera on is a global opera on (t == 2), record the last global opera on (last update
me, kind of last update).

Step 4: Iterate through each character in the string:

a. Check if there's no global opera on (!fill) or if the last update me of the character is greater
than or equal to the last global opera on's me.

- If true, print the character directly.

- If false, check the kind of the global opera on:

- If the kind is 2, make the character lowercase.

- If the kind is 1, make the character uppercase.

Step 5: Print a newline character to separate the output.

Step 6: End

This algorithm maintains a vector status to keep track of each character's status, including the last
update me and the current character. It also tracks the last global opera on. During the prin ng step,
it checks whether the character's last update was affected by a global opera on and adjusts the
character accordingly.

Code:

#include <string>

#include <iostream>

#include <vector>

#include <u lity>


#include <op onal>

int main() {

using namespace std;

int N;

string S;

cin >> N >> S;

vector<pair<int, char>> status(N); // Individual opera on (last update me, current character)

for (int i = 0; i < N; ++i)

status[i] = {0, S[i]}; // Time 0 at first

int Q;

cin >> Q;

op onal<pair<int, int>> fill = nullopt; // Global opera on (last update me, kind of last update)

for (int i = 0; i < Q; ++i) { // Opera on at me i

int t, x;

char c;

cin >> t >> x >> c;

if (t == 1) // individual opera on

status[x - 1] = {i, c};

else // global opera on

fill = {i, t};

for (const auto&[ me, c] : status)

if (!fill || me >= fill->first) // If global opera on is absent or last update is later,

cout << c; // print it directly

else if (fill->second == 2) // otherwise, depending on the kind of the global opera on,
cout << sta c_cast<char>(tolower(c)); // make it lower

else

cout << sta c_cast<char>(toupper(c)); // or upper

cout << endl;

return 0;

}
E - Roulettes  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 475 points

Problem Statement
There are N  roulette wheels. The i-th (1 ≤ i ≤ N ) wheel has Pi  integers Si,1 , Si,2 , … , Si,Pi  written on it,
​ ​ ​


and you can play it once by paying Ci  yen. When you play the i-th wheel once, an integer j  between 1

 and Pi , inclusive, is chosen uniformly at random, and you earn Si,j  points.


​ ​

The points you earn from the wheels are determined independently of past results.

Takahashi wants to earn at least M  points. Takahashi will act to minimize the amount of money he pays
before he earns at least M  points. After each play, he can choose which wheel to play next based on the
previous results.

Find the expected amount of money Takahashi will pay before he earns at least M  points.

More formal definition

Constraints
1 ≤ N ≤ 100
1 ≤ M ≤ 100
1 ≤ Ci ≤ 104  (1 ≤ i ≤ N ) ​

1 ≤ Pi ≤ 100 (1 ≤ i ≤ N ) ​

0 ≤ Si,j ≤ M  (1 ≤ i ≤ N , 1 ≤ j ≤ Pi ) ​ ​

Pi ​

∑ Si,j > 0 (1 ≤ i ≤ N )


​ ​

j=1
All input values are integers.

Input
The input is given from Standard Input in the following format:

N M
C1 P1 S1,1 S1,2 … S1,P1
​ ​ ​ ​


C2 P2 S2,1 S2,2 … S2,P2


​ ​ ​ ​



CN PN SN ,1 SN ,2 … SN ,PN
​ ​ ​ ​



Output
Print the expected amount of money Takahashi will pay until he earns at least M  points in a single line.
Your output will be considered correct when the relative or absolute error from the true value is at most 
10−5 .

Sample Input 1  Copy

Copy
3 14
100 2 5 9
50 4 1 2 4 8
70 5 2 4 2 8 8

Sample Output 1  Copy

Copy
215.913355350494384765625

For instance, Takahashi can play the wheels as follows.

Pay 50 yen to play roulette 2 and earn S2,4 = 8 points.


Pay 50 yen to play roulette 2 and earn S2,1 = 1 point.


Pay 100 yen to play roulette 1 and earn S1,1 = 5 points. He has earned a total of 8 + 1 + 5


​ ≥ 14
 points, so he quits playing.

In this case, he pays 200 yen before earning 14 points.

Your output will be considered correct when the relative or absolute error from the true value is at most 
10−5 , so outputs such as 215.9112 and 215.9155 would also be considered correct.

Sample Input 2  Copy

Copy
2 100
1 2 1 2
10 6 0 0 0 0 0 100

Sample Output 2  Copy

Copy
60

It is optimal to keep spinning roulette 2 until you get 100 points.

Sample Input 3  Copy

Copy
20 90
3252 9 0 4 2 7 3 2 3 2 4
2147 1 1
4033 8 0 4 1 7 5 2 5 0
3795 6 6 6 2 3 2 2
3941 7 2 4 4 7 2 0 5
2815 6 2 1 0 5 2 2
3020 2 3 6
3858 9 4 2 7 3 0 4 4 6 5
4533 10 3 6 4 0 6 4 4 2 7 7
4198 8 6 7 0 6 3 6 5 6
3739 8 2 7 1 5 1 4 4 7
2465 4 1 4 0 1
4418 9 7 6 2 4 6 1 5 0 7
5450 12 0 4 4 7 7 4 4 5 4 5 3 7
4196 9 1 6 5 5 7 2 3 6 3
4776 9 2 2 7 3 6 6 1 6 6
2286 3 3 5 6
3152 3 4 1 5
3509 7 0 6 7 0 1 0 3
2913 6 0 1 5 0 5 6

Sample Output 3  Copy

Copy
45037.072314895291126319493887599716
Algorithm:

The provided editorial explains the algorithm for solving problem E called "Roule es" from the
programming contest. The problem involves finding the expected amount of money needed to reach
a certain number of points in a game of roule e with mul ple wheels.

Here's a high-level overview of the algorithm:

1. Construct the Wheel Informa on: Read the input, which includes the parameters for each wheel:
cost `C`, number of integers `P`, and the values `S` on the wheel.

2. Preprocess the Wheel Informa on:

- Remove zeros from the list of values `S` on each wheel and adjust the cost `C` and the number of
integers `P` accordingly. This is done to avoid 0 points in the computa on.

3. Compute Expected Amounts of Money (e[i]):

- Compute the expected amount of money required to reach `M` points, star ng from `i` points, for
each `i` from `M-1` down to `0`.

- For each `i` and each wheel:

- Calculate the expected value a0er playing the wheel, considering the values `S` on the wheel that
don't exceed the target `M` points.

- Update the expected amount `e[i]` with the minimum cost (`C`) plus the average of the expected
values a0er playing the wheel, considering the number of integers (`P`).

4. Print the Answer:

- The answer is the expected amount of money (`e[0]`) required to reach the target `M` points
star ng from 0 points.

Code:

#include <string>

#include <iostream>

#include <vector>

#include <u lity>

#include <op onal>

int main() {

using namespace std;

int N;

string S;

cin >> N >> S;


vector<pair<int, char>> status(N); // Individual opera on (last update me, current character)

for (int i = 0; i < N; ++i)

status[i] = {0, S[i]}; // Time 0 at first

int Q;

cin >> Q;

op onal<pair<int, int>> fill = nullopt; // Global opera on (last update me, kind of last update)

for (int i = 0; i < Q; ++i) { // Opera on at me i

int t, x;

char c;

cin >> t >> x >> c;

if (t == 1) // individual opera on

status[x - 1] = {i, c};

else // global opera on

fill = {i, t};

for (const auto&[ me, c] : status)

if (!fill || me >= fill->first) // If global opera on is absent or last update is later,

cout << c; // print it directly

else if (fill->second == 2) // otherwise, depending on the kind of the global opera on,

cout << sta c_cast<char>(tolower(c)); // make it lower

else

cout << sta c_cast<char>(toupper(c)); // or upper

cout << endl;

return 0;

}
F - A Certain Game  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 475 points

Problem Statement
N  players, player 1, player 2, ..., player N , participate in a game tournament. Just before the
tournament starts, each player forms a one-person team, so there are N  teams in total.

The tournament has a total of N − 1 matches. In each match, two different teams are chosen. One team
goes first, and the other goes second. Each match will result in exactly one team winning. Specifically,
for each i = 1, 2, … , N − 1, the i-th match proceeds as follows.
The team with player pi  goes first, and the team with player qi  goes second.
​ ​

Let a and b be the numbers of players in the first and second teams, respectively. The first team
a b
wins with probability  a+b , and the second team wins with probability  a+b
​ .

Then, the two teams are combined into a single team.

The result of each match is independent of those of the others.

For each of the N  players, print the expected number of times the team with that player wins throughout
the tournament, modulo 998244353.

How to print an expected value modulo 998244353

Constraints
2 ≤ N ≤ 2 × 105
1 ≤ pi , qi ≤ N
​ ​

Just before the i-th match, player pi  and player qi  belong to different teams.
​ ​

All input values are integers.

Input
The input is given from Standard Input in the following format:

N
p1 q1
​ ​

p2 q2
​ ​


pN −1 qN −1
​ ​
Output
For each i = 1, 2, … , N , print Ei , the expected number, modulo 998244353, of times the team with

player i wins throughout the tournament, separated by spaces, in the following format:

E1 E2 … EN
​ ​ ​

Sample Input 1  Copy

Copy
5
1 2
4 3
5 3
1 4

Sample Output 1  Copy

Copy
698771048 698771048 964969543 964969543 133099248

We call a team formed by player x1 , player x2 , …, player xk  as team {x1 , x2 , … , xk }.


​ ​ ​ ​ ​ ​

The first match is played by team {1}, with player 1, and team {2}, with player 2. Team {1} wins
with probability  12 , and team {2} wins with probability  12 . Then, the two teams are combined into a
​ ​

single team {1, 2}.


The second match is played by team {4}, with player 4, and team {3}, with player 3. Team {4}
 wins with probability  12 , and team {3} wins with probability  12 . Then, the two teams are combined
​ ​

into a single team {3, 4}.


The third match is played by team {5}, with player 5, and team {3, 4}, with player 3. Team {5}
 wins with probability  13 , and team {3, 4} wins with probability  23 . Then, the two teams are
​ ​

combined into a single team {3, 4, 5}.


The fourth match is played by team {1, 2}, with player 1, and team {3, 4, 5}, with player 4. Team 
{1, 2} wins with probability  25 , and team {3, 4, 5} wins with probability  35 . Then, the two teams are
​ ​

combined into a single team {1, 2, 3, 4, 5}.

The expected numbers of times the teams with players 1, 2, 3, 4, 5 win throughout the tournament, 
9 9 53 53 14
E1 , E2 , E3 , E4 , E5 , are  10
​ ​ ​ ​ , 10 , 30 , 30 , 15 , respectively.
​ ​ ​ ​ ​ ​

Sample Input 2  Copy

Copy
15
9 2
8 10
13 6
12 11
7 10
4 10
14 2
5 4
1 15
15 2
6 9
8 11
6 3
2 8

Sample Output 2  Copy

Copy
43970290 310168785 806914186 501498951 950708909 272140427 335124893 168750835 310168785 168750835 280
Algorithm:

1. Initialize necessary data structures:


 Create a list called parent with N elements, each initialized to its own
index. This list will be used to track the parent of each player's team in
the Union-Find data structure.
 Create a list called size with N elements, each initialized to 1. This list
will track the size of each connected component.
 Create a list called base_expect with N elements, each initialized to 0.
This list will store the base expected value of each connected
component.
 Create a list called delta with N elements, each initialized to 0. This list
will store the difference between the expected number of wins at a
certain point and the actual number of wins.
 Create a list called wins with N elements, each initialized to 1. This list
will store the expected number of times the team with each player wins.
2. Implement the find function in the Union-Find data structure:
 Given a player index x, find its parent using the parent list.
 Perform path compression to optimize future find operations by
setting the parent of all visited nodes to the root of the connected
component.
3. Implement the merge function in the Union-Find data structure:
 Given player indices x and y, and the probability of player x winning a
match w, merge the connected components containing players x and y:
 Find the roots (px, py) of the connected components using the
find function.
 If px is not equal to py, merge the components:
 Update the parent of px to py.
 Update the size of py by adding the size of px.
 Update the base_expect of py by adding the base_expect of
px and the probability of player x winning.
 Update the delta of py by adding the delta of px.
 Update the wins of px and py using the size of the merged
components and the probability of player x winning.
4. Iterate through the given matches and apply the merge function to update the
Union-Find data structure.
5. Calculate the total number of wins and the total base expected value for all
connected components in the Union-Find data structure.
6. Calculate the expected number of times the team with each player wins:
 For each player index i , calculate the expected number of wins as the
sum of:
 base_expect of the connected component containing player i.
 delta of the connected component containing player i
multiplied by the inverse of the size of that component.
 wins of player i multiplied by the inverse of the size of the
connected component containing player i.
 Return the results as a list.
7. Print the expected number of times the team with each player wins, modulo
998244353.

Code:

MOD = 998244353

def mod_inverse(a):

return pow(a, MOD - 2, MOD)

def solve_game(N, matches):

parent = list(range(N))

size = [1] * N

base_expect = [0] * N

delta = [0] * N

wins = [1] * N

def find(x):

if parent[x] != x:

parent[x] = find(parent[x])

return parent[x]

def merge(x, y, w):

px, py = find(x), find(y)

if px != py:

parent[px] = py

size[py] += size[px]

base_expect[py] += base_expect[px] + w

delta[py] += delta[px]
wins[px] = size[px] * w * mod_inverse(size[px] + size[py])

wins[py] = size[py] * w * mod_inverse(size[px] + size[py])

for i, (p, q) in enumerate(matches):

merge(p - 1, q - 1, i + 2)

total_wins = sum(wins)

total_expect = 0

for i in range(N):

total_expect += base_expect[find(i)] + delta[find(i)] * mod_inverse(size[find(i)])

result = [(total_expect + wins[i] * mod_inverse(size[find(i)]) * total_wins) % MOD for i in range(N)]

return result

# Sample Input 1

N1 = 5

matches1 = [(1, 2), (4, 3), (5, 3), (1, 4)]

print(*solve_game(N1, matches1)) # Output: 698771048 698771048 964969543 964969543


133099248

# Sample Input 2

N2 = 15

matches2 = [(9, 2), (8, 10), (13, 6), (12, 11), (7, 10), (4, 10), (14, 2), (5, 4), (1, 15), (15, 2), (6, 9), (8, 11),
(6, 3), (2, 8)]

print(*solve_game(N2, matches2))
G - Amulets  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 575 points

Problem Statement
There are N  monsters in a cave: monster 1, monster 2, …, monster N . Each monster has a positive
integer attack power and a type represented by an integer between 1 and M , inclusive. Specifically,
for i = 1, 2, … , N , the attack power and type of monster i are Ai  and Bi , respectively.
​ ​

Takahashi will go on an adventure in this cave with a health of H  and some of the M  amulets: amulet 1,
amulet 2, …, amulet M .

In the adventure, Takahashi performs the following steps for i = 1, 2, … , N  in this order (as long as his
health does not drop to 0 or below).

If Takahashi has not brought amulet Bi  with him, monster i will attack him and decrease his health

by Ai .

Then,
if his health is greater than 0, he defeats monster i;
otherwise, he dies without defeating monster i and ends his adventure.

Solve the following problem for each K = 0, 1, … , M  independently.

Find the maximum number of monsters that Takahashi can defeat when choosing K  of the M
 amulets to bring on the adventure.

The constraints guarantee that there is at least one monster of type i for each i = 1, 2, … , M .

Constraints
1 ≤ M ≤ N ≤ 3 × 105
1 ≤ H ≤ 109
1 ≤ Ai ≤ 109

1 ≤ Bi ≤ M​

For each 1 ≤ i ≤ M , there is 1 ≤ j ≤ N  such that Bj = i.


All input values are integers.

Input
The input is given from Standard Input in the following format:
N M H
A1 B1
​ ​

A2 B2
​ ​


AN BN ​ ​

Output
For each i
= 0, 1, 2, … , M , let Xi  be the maximum number of monsters that Takahashi can defeat

when K = i. Print X0 , X1 , … , XM  separated by spaces in the following format:


​ ​ ​

X0 X1 … XM
​ ​ ​

Sample Input 1  Copy

Copy
7 3 7
3 2
1 1
4 2
1 2
5 1
9 3
2 3

Sample Output 1  Copy

Copy
2 5 7 7

Consider the case K = 1. Here, Takahashi can bring amulet 2 to defeat the maximum possible number
of monsters, which is 5. The adventure proceeds as follows.

For i = 1, he avoids the attack of monster 1 since he has amulet 2. Then, he defeats monster 1.
For i = 2, he takes the attack of monster 2 and his health becomes 6 since he does not have
amulet 1. Then, he defeats monster 2.
For i = 3, he avoids the attack of monster 3 since he has amulet 2. Then, he defeats monster 3.
For i = 4, he avoids the attack of monster 4 since he has amulet 2. Then, he defeats monster 4.
For i = 5, he takes the attack of monster 5 and his health becomes 1 since he does not have
amulet 1. Then, he defeats monster 5.
For i = 6, he takes the attack of monster 6 and his health becomes −8 since he does not have
amulet 3. Then, he dies without defeating monster 6 and ends his adventure.

Similarly, when K = 0, he can defeat 2 monsters; when K = 2, he can defeat all 7 monsters by bringing


amulets 2 and 3; when K = 3, he can defeat all 7 monsters by bringing amulets 1, 2, and 3.
Sample Input 2  Copy

Copy
15 5 400
29 5
27 4
79 1
27 2
30 3
4 1
89 2
88 3
75 5
3 1
39 4
12 1
62 4
38 2
49 1

Sample Output 2  Copy

Copy
8 12 15 15 15 15
Algorithm:

1. Preprocessing and Setup


 Include necessary headers.
 Define constants and type aliases (e.g., ll, F).
 Define macros, data structures (e.g., segment tree), and helper
functions (e.g., sorting).
 Set up basic I/O operations and the solve function.
2. Read Input and Prepare Data
 Read input integers N, M, and H.
 Read arrays A and B.
 Prepare virtual weights based on the input arrays.
 Create pairs of (value, index) for sorting.
 Initialize the segment tree (seg) with initial values using the segtree
template.
3. Dynamic Programming Approach - Part 1
 Create vectors to store indices (G) and indices' current position (ind).
 Update the segment tree (seg) with initial values based on the indices
provided by G.
4. Dynamic Programming Approach - Main Loop
 Initialize the answer vector (ans) and virtual weight vector (S).
 Iterate through the input data (N iterations).
 For each iteration, update the segment tree and calculate temporary
results.
 Use binary search to find a suitable position (b) for the current target in
the segment tree.
 Update the answer for the current state in the ans vector.
5. Output the Results
 Adjust the values in the answer vector (ans) to get the final result.
 Output the results in the specified format.

Code:

#include <bits/stdc++.h>

#pragma GCC op mize("Ofast")

#pragma GCC op mize("unroll-loops")

using namespace std;

using std::cout;

using std::cin;

using std::endl;

using ll=long long;


using ld=long double;

const ll ILL=2167167167167167167;

const int INF=2100000000;

const int mod=998244353;

#define rep(i,a,b) for (int i=(int)(a);i<(int)(b);i++)

#define all(p) p.begin(),p.end()

template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;

template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}

template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}

template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}

template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}

template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}

template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}

void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}

template<class T> void vec_out(vector<T> &p){for(int i=0;i<(int)(p.size());i++){if(i) cout<<"


";cout<<p[i];}cout<<"\n";}

template<class T> T vec_min(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a)


chmin(ans,x);return ans;}

template<class T> T vec_max(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a)


chmax(ans,x);return ans;}

template<class T> T vec_sum(vector<T> &a){assert(!a.empty());T ans=a[0]-a[0];for(auto &x:a)


ans+=x;return ans;}

int pop_count(long long a){int res=0;while(a){res+=(a&1),a>>=1;}return res;}

namespace atcoder {

namespace internal {

// @param n `0 <= n`

// @return minimum non-nega ve `x` s.t. `n <= 2**x`

int ceil_pow2(int n) {
int x = 0;

while ((1U << x) < (unsigned int)(n)) x++;

return x;

// @param n `1 <= n`

// @return minimum non-nega ve `x` s.t. `(n & (1 << x)) != 0`

int bsf(unsigned int n) {

#ifdef _MSC_VER

unsigned long index;

_BitScanForward(&index, n);

return index;

#else

return __buil n_ctz(n);

#endif

} // namespace internal

template <class S, S (*op)(S, S), S (*e)()> struct segtree {

public:

segtree() : segtree(0) {}

segtree(int n) : segtree(std::vector<S>(n, e())) {}

segtree(const std::vector<S>& v) : _n(int(v.size())) {

log = internal::ceil_pow2(_n);

size = 1 << log;

d = std::vector<S>(2 * size, e());

for (int i = 0; i < _n; i++) d[size + i] = v[i];

for (int i = size - 1; i >= 1; i--) {

update(i);
}

void set(int p, S x) {

assert(0 <= p && p < _n);

p += size;

d[p] = x;

for (int i = 1; i <= log; i++) update(p >> i);

S get(int p) {

assert(0 <= p && p < _n);

return d[p + size];

S prod(int l, int r) {

assert(0 <= l && l <= r && r <= _n);

S sml = e(), smr = e();

l += size;

r += size;

while (l < r) {

if (l & 1) sml = op(sml, d[l++]);

if (r & 1) smr = op(d[--r], smr);

l >>= 1;

r >>= 1;

return op(sml, smr);

S all_prod() { return d[1]; }


template <bool (*f)(S)> int max_right(int l) {

return max_right(l, [](S x) { return f(x); });

template <class F> int max_right(int l, F f) {

assert(0 <= l && l <= _n);

assert(f(e()));

if (l == _n) return _n;

l += size;

S sm = e();

do {

while (l % 2 == 0) l >>= 1;

if (!f(op(sm, d[l]))) {

while (l < size) {

l = (2 * l);

if (f(op(sm, d[l]))) {

sm = op(sm, d[l]);

l++;

return l - size;

sm = op(sm, d[l]);

l++;

} while ((l & -l) != l);

return _n;

template <bool (*f)(S)> int min_leP(int r) {

return min_leP(r, [](S x) { return f(x); });

}
template <class F> int min_leP(int r, F f) {

assert(0 <= r && r <= _n);

assert(f(e()));

if (r == 0) return 0;

r += size;

S sm = e();

do {

r--;

while (r > 1 && (r % 2)) r >>= 1;

if (!f(op(d[r], sm))) {

while (r < size) {

r = (2 * r + 1);

if (f(op(d[r], sm))) {

sm = op(d[r], sm);

r--;

return r + 1 - size;

sm = op(d[r], sm);

} while ((r & -r) != r);

return 0;

private:

int _n, size, log;

std::vector<S> d;

void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }

};
} // namespace atcoder

using namespace atcoder;

using F= pair<ll,ll>;

F op(F a,F b){return {a.first+b.first,a.second+b.second};}

F e(){return {0,0};}

ll target;

bool f(F a){

return target>a.first;

void solve();

// oddloop

int main() {

ios::sync_with_stdio(false);

cin. e(nullptr);

int t=1;

//cin>>t;

rep(i,0,t) solve();

void solve(){

int N,M;

ll H;

cin>>N>>M>>H;

target=H;

vector<ll> A(N),B(N);

rep(i,0,N) cin>>A[i]>>B[i],B[i]--;

vector<ll> S(N);
vector<pair<ll,int>> p;

rep(i,0,M){

p.push_back({0,i});

rep(i,0,N){

S[B[i]]+=A[i];

p.push_back({S[B[i]],B[i]});

vector<vector<int>> G(M);

vector<int> ind(M);

So(p);

segtree<F,op,e> seg(N+M);

rep(i,0,N+M){

G[p[i].second].push_back(i);

rep(i,0,M) seg.set(i,{0,1});

vector<int> ans(M+1);

rep(i,0,M) S[i]=0;

rep(i,0,N){

seg.set(G[B[i]][ind[B[i]]],e());

ind[B[i]]++;

S[B[i]]+=A[i];

seg.set(G[B[i]][ind[B[i]]],{S[B[i]],1});

int b=seg.max_right<f>(0);

auto tmp=seg.prod(0,b);

ans[M-tmp.second]=i+1;

rep(i,0,M) chmax(ans[i+1],ans[i]);

vec_out(ans);

}
Ex - Disk and Segments  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 625 points

Problem Statement
There are N  line segments in a coordinate plane, and the i-th line segment (1 ≤ i ≤ N ) has two points 
(ai , bi ) and (ci , di ) as its endpoints. Here, each line segment includes its endpoints. Additionally, no two
​ ​ ​ ​

line segments share a point.

We want to place a single closed disk in this plane so that it shares a point with each line segment. In
other words, we want to draw a single circle so that each line segment shares a point with either the
circumference of the circle or its interior (or both). Find the smallest possible radius of such a disk.

Constraints
2 ≤ N ≤ 100
0 ≤ ai , bi , ci , di ≤ 1000 (1 ≤ i ≤ N )
​ ​ ​ ​

(ai , bi ) 
= (ci , di ) (1 ≤ i ≤ N )
​ ​ ​ ​

The i-th and j -th line segments do not share a point (1 ≤ i < j ≤ N ).


All input values are integers.

Input
The input is given from Standard Input in the following format:

N
a 1 b 1 c1 d 1
​ ​ ​ ​

a 2 b 2 c2 d 2
​ ​ ​ ​


a N b N cN d N
​ ​ ​ ​

Output
Print the answer in a single line. Your output will be considered correct when the absolute or relative
error from the true value is at most 10−5 .

Sample Input 1  Copy

Copy
4
2 3 2 10
4 0 12 6
4 8 6 3
7 8 10 8

Sample Output 1  Copy

Copy
3.319048676309097923796460081961

The given line segments are shown in the figure below. The closed disk shown in the figure, centered at 
32 − 115 21 − 115 24 − 115
( , ) with a radius of 
​ ​ ​

, shares a point with all the line segments.


4 2 4
​ ​ ​
24 − 115 ​

It is impossible to place a disk with a radius less than   so that it shares a point with all the
4

24 − 115 ​

line segments, so the answer is  .


4

Your output will be considered correct if the absolute or relative error from the true value is at most 10−5 ,
so outputs such as 3.31908 and 3.31902 would also be considered correct.

Sample Input 2  Copy

Copy
20
0 18 4 28
2 21 8 21
3 4 10 5
3 14 10 13
5 9 10 12
6 9 10 6
6 28 10 18
12 11 15 13
12 17 12 27
13 17 20 18
13 27 19 26
16 1 16 13
16 22 19 25
17 22 20 19
18 4 23 4
18 5 23 11
22 16 22 23
23 15 30 15
23 24 30 24
24 0 24 11

Sample Output 2  Copy

Copy
12.875165712523887403637822024952

19817 − 8 5991922 −2305 + 5991922


The closed disk shown in the figure, centered at ( , ) with
​ ​

18 9
​ ​

3757 29 − 44 206618
​ ​

a radius of  , shares a point with all the line segments.


18
Sample Input 3  Copy

Copy
30
526 655 528 593
628 328 957 211
480 758 680 794
940 822 657 949
127 23 250 385
281 406 319 305
277 598 190 439
437 450 725 254
970 478 369 466
421 225 348 141
872 64 600 9
634 460 759 337
878 514 447 534
142 237 191 269
983 34 554 284
694 160 589 239
391 631 22 743
377 656 500 606
390 576 184 312
556 707 457 699
796 870 186 773
12 803 505 586
343 541 42 165
478 340 176 2
39 618 6 651
753 883 47 833
551 593 873 672
983 729 338 747
721 77 541 255
0 32 98 597

Sample Output 3  Copy

Copy
485.264732620930836460637042310401
Algorithm:

Detailed step-by-step algorithm for the given code, which finds the minimum radius
of a closed disk centered at a point (x, y) that shares a point with all the given segments:

1. Input:
Read the number of segments, N.
 Read the coordinates of N segments, where each segment is represented
by four real numbers (a, b, c, d) representing the endpoints (a, b) and (c,
d) of the segment.
2. Distance Calculation:
 Define a function distance_point_and_point that calculates the Euclidean
distance between two points given their coordinates (x, y) and (z, w).
3. Distance from Point to Segment:
 Define a function distance_segment_and_point that calculates the minimum
distance from a given point (x, y) to a segment defined by its endpoints
(a, b) and (c, d). It considers both cases where the point is outside the
segment's bounding box and where it is inside.
4. Minimum Crossing Circle:
 Define a function minimum_crossing_circle that calculates the minimum
radius of a closed circle centered at a given point (x, y) that shares a point
with all segments. This function iterates through all segments and
updates the maximum distance from the point to any segment.
5. Trinary Search for Unimodal Function:
 Define a function minimize_unimodal_function that uses trinary search to
find the minimum value of a unimodal function within a given range. This
function takes as input a left bound (L), a right bound (R), and a function
to minimize within that range.
6. Minimize the Function:
 Use the minimize_unimodal_function function twice:
 First, to find the minimum value of f(x, y) for a fixed x by using a
nested trinary search that minimizes the function
minimum_crossing_circle for a fixed x and varying y.
 Second, to find the minimum value of the unimodal function from
the previous step by varying x.
7. Output:
 Output the minimum radius of the closed circle that shares a point with
all segments, which is the result of the trinary search.
8. Convexity Proofs:
 Prove that the distance function d_p between a point p and another point
(x, y) is convex (Lemma 1).
 Prove that the distance function d_s between a segment s and a point (x,
y) is convex (Lemma 2).
Prove that the maximum of convex functions remains convex (Lemma 3).

9. Convexity of f(x, y):
 Prove that the function f(x, y), which represents the minimum radius of
the circle, is convex based on the convexity properties of d_s and Lemma
3.
10. Convexity of F(x):
 Prove that the function F(x), which represents the minimum value of f(x, y) for a
fixed x, is convex (F(x) is a unimodal function).

Code:

#include <iostream>

#include <tuple>

#include <vector>

#include <cmath>

#include <ranges>

int main() {

using namespace std;

unsigned N;

cin >> N;

using real = double;

using segment_type = tuple<real, real, real, real>;

using point_type = tuple<real, real>;

vector<segment_type> segments(N);

for (auto&&[a, b, c, d] : segments)

cin >> a >> b >> c >> d;

// Distance of two points

const auto distance_point_and_point{[](const point_type &point0, const point_type &point1) {

const auto&[x, y]{point0};

const auto&[z, w]{point1};

return hypot(x - z, y - w);

}};

// Distance of point and segment


const auto distance_segment_and_point{[&](const segment_type &segment, const point_type
&point) {

const auto&[a, b, c, d]{segment};

const auto&[x, y]{point};

if ((a - c) * (a - x) + (b - d) * (b - y) < 0)

return distance_point_and_point({a, b}, {x, y});

if ((c - a) * (c - x) + (d - b) * (d - y) < 0)

return distance_point_and_point({c, d}, {x, y});

return abs((a - c) * (b - y) - (b - d) * (a - x)) / distance_point_and_point({a, b}, {c, d});

}};

// minimum radius of a closed circle centered at the given point that shares a point with all
segments

const auto minimum_crossing_circle{[&](const point_type &point) {

real ret{};

for(const auto& segment : segments)

ret = max(ret, distance_segment_and_point(segment, point));

return ret;

}};

// Use trinary search to find the minimum value of a unimodal func2on

const auto minimize_unimodal_func2on{[](real L, real R, auto &&func2on) {

for (const auto _ : ranges::views::iota(0, 100)) {

auto M1{(L * 2 + R) / 3};

auto M2{(L + 2 * R) / 3};

if (func2on(M1) < func2on(M2))

R = M2;

else

L = M1;

return func2on(L);

}};

cout << minimize_unimodal_func2on(0, 1000, [&](auto x) {

// Find the minimum value of f(x, y) for a fixed x


return minimize_unimodal_func2on(0, 1000, [&](auto y) {

// Given x and y, we can find the minimum radius

return minimum_crossing_circle({x, y});

});

}) << endl;

return 0;

}
THANK YOU
A DETAILED EDITORIAL FOR
ATCODER – KEYENCE PROGRAMMING CONTEST 2023
SUMMER (ATCODER BEGINNER CONTEST 315)

Date of Contest: 19-08-2023

Editorial by
Dr. Dinesh Kumar Anguraj, Asso. Prof., Dept. of CSE.
Website Link: https://atcoder.jp/

Contest URL: https://atcoder.jp/contests/abc315

Mode: Rated & Unrated

Number of Contest Tasks: 7 Tasks

Number of Extra Tasks: 1 Task

Note & Credits: Problem statement and Hints from Atcoder.jp by the users
“en_translator (English) & physics (Japanese)”
CONTEST PROBLEM
STATEMENTS, HINTS AND
ALGORITHMS WITH CODE
A - tcdr  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 100 points

Problem Statement
You are given a string S  consisting of lowercase English letters.
Remove all occurrences of a, e, i, o, u from S  and print the resulting string.
S  contains at least one character other than a, e, i, o, u.

Constraints
S  is a string of length between 1 and 100, inclusive, consisting of lowercase English letters.
S  contains at least one character other than a, e, i, o, u.

Input
The input is given from Standard Input in the following format:

Output
Print the answer.

Sample Input 1  Copy

Copy
atcoder

Sample Output 1  Copy

Copy
tcdr

For S = atcoder, remove the 1-st, 4-th, and 6-th characters to get tcdr.

Sample Input 2  Copy

Copy
xyz
Sample Output 2  Copy

Copy
xyz

Sample Input 3  Copy

Copy
aaaabbbbcccc

Sample Output 3  Copy

Copy
bbbbcccc
Algorithm:

1. Input: Prompt the user to enter a string and store it in the variable S.

2. Ini alize a string vowels with the characters "aeiou" which represent the vowels.

3. Ini alize an empty string result to store the final string with vowels removed.

4. Itera on: Loop through each character char in the input string S:

 Check if char is not in the vowels string (i.e., if it's not a vowel).

 If the above condi on is true, append char to the result string.

5. Output: Print the result string which contains the input string with all vowels removed.

Code:

S = input().strip()

vowels = "aeiou"

result = ''.join([char for char in S if char not in vowels])

print(result)
B - The Middle Day  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 200 points

Problem Statement
In the calendar of AtCoderLand, a year consists of M  months: month 1, month 2, …, month M . The i-th
month consists of Di  days: day 1, day 2, …, day Di .
​ ​

Furthermore, the number of days in a year is odd, that is, D1 ​


+ D2 + ⋯ + DM  is odd.

Find what day of what month is the middle day of the year.
In other words, let day 1 of month 1 be the first day, and find a and b such that the ((D1 ​ + D2 + ⋯ +

DM + 1)/2)-th day is day b of month a.


Constraints
All input values are integers.
1 ≤ M ≤ 100
1 ≤ Di ≤ 100​

D1 + D2 + ⋯ + DM  is odd.
​ ​ ​

Input
The input is given from Standard Input in the following format:

M
D1 D2 … DM
​ ​ ​

Output
Let the answer be day b of month a, and print it in the following format:

a b

Sample Input 1  Copy

Copy
12
31 28 31 30 31 30 31 31 30 31 30 31

Sample Output 1  Copy


Copy
7 2

In this input, a year consists of 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 = 365


 days.
Let us find the middle day, which is the ((365 + 1)/2 = 183)-th day.
Months 1, 2, 3, 4, 5, 6 contain a total of 181 days.
Day 1 of month 7 is the 182-th day.
Day 2 of month 7 is the 183-th day.

Thus, the answer is day 2 of month 7.

Sample Input 2  Copy

Copy
1
1

Sample Output 2  Copy

Copy
1 1

Sample Input 3  Copy

Copy
6
3 1 4 1 5 9

Sample Output 3  Copy

Copy
5 3
Algorithm:

1. Input: Prompt the user to input an integer M, represen ng the number of months. Then
prompt the user to input M integers separated by spaces and store them in a list D. These
integers represent the number of days in each month.

2. Calculate the total number of days by summing up the elements in the list D, and store the
result in the variable total_days.

3. Calculate the index of the middle day using the formula (total_days + 1) // 2. This index will
be used to find the middle day in the total days span.

4. Ini alize variables:

 current_month with 0, which will be used to keep track of the current month being
considered.

 middle_day_index with the index calculated in step 3.

5. Loop:

 While the middle_day_index is greater than the number of days in the current
month (D[current_month]):

 Subtract the number of days in the current month from the


middle_day_index.

 Increment current_month by 1 to move to the next month.

6. Output: Print the current month index plus 1 (since months are typically represented star ng
from 1) and the remaining value of middle_day_index. This represents the month and day in
the middle of the total days spanned by the given months.

Code:

M = int(input())

D = list(map(int, input().split()))

total_days = sum(D)

middle_day_index = (total_days + 1) // 2

current_month = 0

while middle_day_index > D[current_month]:

middle_day_index -= D[current_month]

current_month += 1

print(current_month + 1, middle_day_index)
C - Flavors  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 300 points

Problem Statement
We have N  cups of ice cream.
The flavor and deliciousness of the i-th cup are Fi  and Si , respectively (Si  is an even number).
​ ​ ​

You will choose and eat two of the N  cups.


Your satisfaction here is defined as follows.

Let s and t (s ≥ t) be the deliciousness of the eaten cups.


If the two cups have different flavors, your satisfaction is s + t.
t
Otherwise, your satisfaction is s + .
2

Find the maximum achievable satisfaction.

Constraints
All input values are integers.
2 ≤ N ≤ 3 × 105
1 ≤ Fi ≤ N ​

2 ≤ Si ≤ 109 ​

Si  is even.

Input
Input is given from Standard Input in the following format:

N
F1 S 1
​ ​

F2 S 2
​ ​


FN S N ​ ​

Output
Print the answer as an integer.

Sample Input 1  Copy


Copy
4
1 4
2 10
2 8
3 6

Sample Output 1  Copy

Copy
16

Consider eating the second and fourth cups.

The second cup has a flavor of 2 and deliciousness of 10.


The fourth cup has a flavor of 3 and deliciousness of 6.
Since they have different flavors, your satisfaction is 10 + 6 = 16.

Thus, you can achieve the satisfaction of 16.


You cannot achieve a satisfaction greater than 16.

Sample Input 2  Copy

Copy
4
4 10
3 2
2 4
4 12

Sample Output 2  Copy

Copy
17

Consider eating the first and fourth cups.

The first cup has a flavor of 4 and deliciousness of 10.


The fourth cup has a flavor of 4 and deliciousness of 12.
Since they have the same flavor, your satisfaction is 12 + 10
2 ​ = 17.

Thus, you can achieve the satisfaction of 17.


You cannot achieve a satisfaction greater than 17.
Algorithm:

Main Program:

 Read an integer n, which represents the number of items.

 Create a 2D vector bk of size n+1 to store the items. Each sub-vector bk[i] represents items
with the same first component (f) as i.

 Loop for n itera"ons:

 Read integers f and s, which represent the two components of an item.

 Store the item in the appropriate sub-vector bk[f].

Processing Steps:

 Ini"alize an integer variable res to store the maximum possible value.

 Create a vector best to store the best values from each sub-vector.

 Loop through each sub-vector in bk from index 1 to n:

 Sort the sub-vector in descending order (to consider items with the highest second
component first).

 If the sub-vector has at least two items, calculate the value by adding the two largest
second components, divided by 2, and update res if the calculated value is greater
than the current res.

 If the sub-vector has at least one item, add the largest second component to the best
vector.

 Sort the best vector in descending order.

 If the best vector has at least two items, calculate the value by adding the two largest values
and update res if the calculated value is greater than the current res.

 Print the maximum possible value res.

Summary:

The code processes a list of items, where each item has two components f and s. It iterates through
the items, categorizing them based on their f component into sub-vectors. It then calculates the
maximum possible value by considering various combina"ons of items based on specific condi"ons
and outputs the result. The goal of the code is to maximize the total value by selec"ng and combining
items op"mally.

Code:

#include<bits/stdc++.h>

using namespace std;


int main(){

int n;

cin >> n;

vector<vector<int>> bk(n+1);

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

int f,s;

cin >> f >> s;

bk[f].push_back(s);

int res=0;

vector<int> best;

for(int i=1;i<=n;i++){

sort(bk[i].begin(),bk[i].end());

reverse(bk[i].begin(),bk[i].end());

if(bk[i].size()>=2){

res=max(res,bk[i][0]+bk[i][1]/2);

if(bk[i].size()>=1){

best.push_back(bk[i][0]);

sort(best.begin(),best.end());

reverse(best.begin(),best.end());

if(best.size()>=2){res=max(res,best[0]+best[1]);}

cout << res << "\n";

return 0;

}
D - Magical Cookies  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 400 points

Problem Statement
There are H × W  cookies in H  rows and W  columns.
The color of the cookie at the i-row from the top and j -th column from the left is represented by a
lowercase English letter ci,j . ​

We will perform the following procedure.

1. For each row, perform the following operation: if there are two or more cookies remaining in the row
and they all have the same color, mark them.

2. For each column, perform the following operation: if there are two or more cookies remaining in the
column and they all have the same color, mark them.

3. If there are any marked cookies, remove them all and return to 1; otherwise, terminate the procedure.

Find the number of cookies remaining at the end of the procedure.

Constraints
2 ≤ H, W ≤ 2000
ci,j  is a lowercase English letter.

Input
The input is given from Standard Input in the following format:

H W
c1,1 c1,2 … c1,W
​ ​

c2,1 c2,2 … c2,W


​ ​


cH,1 cH,2 … cH,W
​ ​ ​

Output
Print the answer.
Sample Input 1  Copy

Copy
4 3
aaa
aaa
abc
abd

Sample Output 1  Copy

Copy
2

The procedure is performed as follows.

1. Mark the cookies in the first and second rows.


2. Mark the cookies in the first column.
3. Remove the marked cookies.

At this point, the cookies look like the following, where . indicates a position where the cookie has been
removed.

...
...
.bc
.bd

1. Do nothing.
2. Mark the cookies in the second column.
3. Remove the marked cookies.

At this point, the cookies look like the following, where . indicates a position where the cookie has been
removed.

...
...
..c
..d

1. Do nothing.
2. Do nothing.
3. No cookies are marked, so terminate the procedure.

The final number of cookies remaining is 2.

Sample Input 2  Copy

Copy
2 5
aaaaa
abcde
Sample Output 2  Copy

Copy
4

Sample Input 3  Copy

Copy
3 3
ooo
ooo
ooo

Sample Output 3  Copy

Copy
0
Algorithm:

Main Program:

 Read two integers h and w, which represent the dimensions of the grid.

 Create a 2D vector c to store the characters in the grid.

 Loop through the rows and columns of the grid and read each character into the corresponding
posi on in the vector c.

Processing Steps:

 Create two 2D vectors x and y, each of size (h, 26) and (w, 26) respec vely.

 x[i][j] stores the count of character 'a' + j in the i-th row.

 y[i][j] stores the count of character 'a' + j in the i-th column.

 Loop through the grid to fill the x and y vectors:

 Increment the corresponding character count in the x vector for each row and in the
y vector for each column.

 Ini alize two variables hc and wc with the values of h and w respec vely. These variables will
keep track of the current number of rows and columns that haven't been excluded.

 Create two boolean vectors fx and fy, each of size h and w respec vely. These vectors will be
used to mark rows and columns that are excluded.

 Loop for a total of h + w itera ons:

 Create empty vectors ux and uy to store pairs of row and column indices that sa sfy
certain condi ons.

 Loop through the rows:

 If row i is already excluded (fx[i] is true), skip it.

 For each character count x[i][j], if it equals wc and wc is greater than or equal
to 2, add the pair (i, j) to ux.

 Loop through the columns:

 If column i is already excluded (fy[i] is true), skip it.

 For each character count y[i][j], if it equals hc and hc is greater than or equal
to 2, add the pair (i, j) to uy.

 Process the pairs stored in ux and uy:

 For each pair (i, j) in ux, mark the row i as excluded (fx[i] = true), decrement all y[i][j]
counts by 1, and decrement hc by 1.

 For each pair (i, j) in uy, mark the column i as excluded (fy[i] = true), decrement all
x[i][j] counts by 1, and decrement wc by 1.

Prin$ng the Result:


 A1er the itera ons, calculate the result by mul plying hc and wc, which represents the
number of remaining rows and columns that haven't been excluded.

 Print the result.

Summary:

The code processes a grid of characters and itera vely eliminates certain rows and columns based on
certain condi ons. It then calculates and prints the product of the remaining row and column counts,
effec vely giving the count of the remaining cells in the grid a1er applying the opera ons. The
opera ons involve selec ng rows and columns where certain character counts are met, and excluding
those that fulfill the condi ons.

Code:

#include <iostream>

#include <vector>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

int main() {

int h, w;

cin >> h >> w;

vector<vector<char>> c(h, vector<char>(w));

rep(i, h) rep(j, w) cin >> c[i][j];

vector<vector<int>> x(h, vector<int>(26));

vector<vector<int>> y(w, vector<int>(26));

rep(i, h) rep(j, w) {

x[i][c[i][j] - 'a']++;

y[j][c[i][j] - 'a']++;

int hc = h, wc = w;

vector<bool> fx(h), fy(w);

rep(_, h + w) {

vector<pair<int, int>> ux, uy;

rep(i, h) {

if (fx[i]) con nue;


rep(j, 26) {

if (x[i][j] == wc && wc >= 2) {

ux.push_back({ i, j });

rep(i, w) {

if (fy[i]) con nue;

rep(j, 26) {

if (y[i][j] == hc && hc >= 2) {

uy.push_back({ i, j });

for (pair<int, int> p : ux) {

fx[p.first] = true;

rep(i, w) y[i][p.second]--;

hc--;

for (pair<int, int> p : uy) {

fy[p.first] = true;

rep(i, h) x[i][p.second]--;

wc--;

cout << hc * wc << '\n';

}
E - Prerequisites  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 425 points

Problem Statement
We have N  books numbered 1 to N .
Book i assumes that you have read Ci  books, the j -th of which is book Pi,j : you must read all these Ci
​ ​ ​

 books before reading book i.


Here, you can read all the books in some order.

You are trying to read the minimum number of books required to read book 1.
Print the numbers of the books you must read excluding book 1 in the order they should be read. Under
this condition, the set of books to read is uniquely determined.
If there are multiple reading orders that satisfy the condition, you may print any of them.

Constraints
2 ≤ N ≤ 2 × 105
0 ≤ Ci < N ​

N
∑i=1 Ci ≤ 2 × 105
​ ​

C1 ≥ 1 ​

1 ≤ Pi,j ≤ N ​

Pi,j =
 Pi,k  for 1 ≤ j < k ≤ Ci .
​ ​ ​

It is possible to read all the books.

Input
The input is given from Standard Input in the following format:

N
C1 P1,1 … P1,C1
​ ​


C2 P2,1 … P2,C2
​ ​



CN PN ,1 … PN ,CN
​ ​


Output
Print the numbers of the books you must read to read book 1 in the order they should be read, with
spaces in between.
Sample Input 1  Copy

Copy
6
3 2 3 4
2 3 5
0
1 5
0
0

Sample Output 1  Copy

Copy
5 3 4 2

To read book 1, you must read books 2, 3, 4; to read book 2, you must read books 3, 5; to read book 4,
you must read book 5. To read books 3, 5, 6, you do not have to read any other books.

For example, if you read books 5, 3, 4, 2 in this order, you can read book 1. This is a correct answer,
because you will never be able to read book 1 with three or fewer books read. As another example,
reading books 3, 5, 4, 2 in this order also allows you to read book 1 with 4 books read.

Sample Input 2  Copy

Copy
6
1 2
1 3
1 4
1 5
1 6
0

Sample Output 2  Copy

Copy
6 5 4 3 2

Sample Input 3  Copy

Copy
8
1 5
1 6
1 7
1 8
0
0
0
0
Sample Output 3  Copy

Copy
5
Algorithm:

Step 1: topological_sort Func on

 This func on performs a topological sort on a given directed graph represented by an


adjacency list.

 It calculates the in-degrees of each node (vertex) by itera ng through the graph and
incremen ng in-degrees for adjacent nodes.

 It ini alizes a queue and adds all nodes with in-degree 0 to the queue.

 The main loop processes nodes in the queue, reducing in-degrees for their neighbors and
adding neighbors with reduced in-degrees of 0 to the queue.

 The nodes are added to the result vector res in the order they are dequeued from the queue.

 The func on returns the resul ng topologically sorted order.

Main Program:

 Read the integer n, which represents the number of nodes (tasks) in the graph.

 Create a graph vector of vectors to represent the adjacency list of the graph.

 For each node from 0 to n-1:

 Read the integer c, which represents the number of tasks dependent on this node.

 Read the indices of the dependent nodes and store them in the corresponding
adjacency list of the current node.

 Perform a breadth-first traversal from node 0 to iden fy reachable nodes (using the f vector)
and mark them as reachable.

 Calculate the topological order of the graph using the topological_sort func on and store it in
vector t.

 Calculate the order of nodes using the topological order t.

 Ini alize an ans vector to store the tasks that are reachable and need to be performed.

 Sort the tasks in descending order of their posi on in the topological order and store the
indices of tasks in the ans vector.

 Print the tasks in the order specified in the problem statement (each task index + 1) with
spaces and a newline character.

Summary: The code performs a topological sort to determine the order in which tasks can be executed
based on their dependencies. It then sorts the reachable tasks in descending topological order and
outputs the result. This kind of algorithm is o.en used in scheduling problems where tasks have
dependencies on each other.
Code:

#include <iostream>

#include <vector>

#include <queue>

#include <algorithm>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

vector<int> topological_sort(vector<vector<int>> graph) {

int n = graph.size();

vector<int> indegree(n);

for (int i = 0; i < n; i++) for (int j : graph[i]) indegree[j]++;

vector<int> res;

queue<int> que;

for (int i = 0; i < n; i++) if (indegree[i] == 0) que.push(i);

while (!que.empty()) {

int ver = que.front(); que.pop();

res.push_back(ver);

for (int i : graph[ver]) {

indegree[i]--;

if (indegree[i] == 0) que.push(i);

return res;

int main() {

int n;

cin >> n;

vector<vector<int>> graph(n, vector<int>());

rep(i, n) {
int c;

cin >> c;

rep(_, c) {

int v;

cin >> v;

v--;

graph[i].push_back(v);

queue<int> que;

que.push(0);

vector<bool> f(n);

while (!que.empty()) {

int q = que.front(); que.pop();

for (int i : graph[q]) {

if (!f[i]) {

f[i] = true;

que.push(i);

vector<int> t = topological_sort(graph);

vector<int> order(n);

rep(i, n) order[t[i]] = i;

vector<int> ans;

for (int i = 1; i < n; i++) if (f[i]) ans.push_back(i);

sort(ans.begin(), ans.end(), [&](int x, int y) {return order[x] > order[y]; });

for (int i = 0; i < ans.size(); i++) cout << ans[i] + 1 << " \n"[i == ans.size() - 1];

}
F - Shortcuts  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 500 points

Problem Statement
There is a race through checkpoints 1, 2, … , N  in this order on a coordinate plane.
The coordinates of checkpoint i are (Xi , Yi ), and all checkpoints have different coordinates.
​ ​

Checkpoints other than checkpoints 1 and N  can be skipped.


However, let C  be the number of checkpoints skipped, and the following penalty will be imposed:

2C−1  if C > 0, and


0 if C = 0.

Let s be the total distance traveled (Euclidean distance) from checkpoint 1 to checkpoint N  plus the
penalty.
Find the minimum achievable value as s.

Constraints
All input values are integers.
2 ≤ N ≤ 104
0 ≤ Xi , Yi ≤ 104 ​ ​

(Xi , Yi ) 
​ = (Xj , Yj ) if i =

j.​ ​

Input
The input is given from Standard Input in the following format:

N
X1 Y 1
​ ​

X2 Y 2
​ ​


XN Y N ​ ​

Output
Print the answer. Your output is considered correct if the absolute or relative error from the true value is
at most 10−5 .
Sample Input 1  Copy

Copy
6
0 0
1 1
2 0
0 1
1 0
2 1

Sample Output 1  Copy

Copy
5.82842712474619009753

Consider passing through checkpoints 1, 2, 5, 6 and skip checkpoints 3, 4.

Move from checkpoint 1 to 2. The distance between them is  2.


Move from checkpoint 2 to 5. The distance between them is 1.


Move from checkpoint 5 to 6. The distance between them is  2.

Two checkpoints are skipped, so the penalty of 2 is imposed.

In this way, you can achieve s = 3 + 2 2 ≈ 5.828427.


You cannot make s smaller than this value.

Sample Input 2  Copy

Copy
10
1 8
3 7
9 4
4 9
6 1
7 5
0 0
1 3
6 8
6 4

Sample Output 2  Copy

Copy
24.63441361516795872523

Sample Input 3  Copy

Copy
10
34 24
47 60
30 31
12 97
87 93
64 46
82 50
14 7
17 24
3 78

Sample Output 3  Copy

Copy
110.61238353245736230207
Algorithm:

Step 1: dist Func on This func on calculates the Euclidean distance between two points represented
by the pairs (x1, y1) and (x2, y2) using the formula sqrt((x1 - x2)^2 + (y1 - y2)^2).

Step 2: Ini aliza on

 Read the value of n, which represents the number of points.

 Create a vector vp to store the coordinates of the points as pairs (x, y).

 Create a set st to keep track of the points encountered (used to remove duplicates).

Step 3: Input Points

 Loop through each point index i from 0 to n-1.

 Read the coordinates of the point (x, y) and store it in the vector vp.

 Insert the point into the set st.

Step 4: Dynamic Programming

 Create a 2D vector dp of size (n, 60) to store the dynamic programming table.

 Ini alize all entries of dp to a very large value lg.

Step 5: Dynamic Programming Loop

 Iterate over the points from index 1 to n-1 (outer loop).

 For each point vp[i], iterate over the previous points from index i-1 to 0 (inner loop).

 Calculate the number of points skipped between vp[j] and vp[i] as skip = i - j
- 1.

 For each possible skip count k, update the entry dp[i][k + skip] by considering
the minimum of the current value and the sum of dp[j][k] (cost of reaching
vp[j]) and the distance between vp[j] and vp[i].

 The idea here is to calculate the cost of reaching vp[i] from all previous points
vp[j] with different skip counts k.

Step 6: Penalty and Minimum Path

 Ini alize res as a large value lg to store the minimum total cost.

 Iterate over the possible skip counts (from 0 to 59) to calculate the minimum total cost for
each skip count:

 For each skip count i, calculate a penalty value pen that depends on the skip count.
The penalty is 2^(i-1) if i is greater than 0 and 0 otherwise.

 Update res with the minimum of the sum of dp[n-1][i] (cost of reaching the last point)
and the calculated penalty pen.

Step 7: Print the Result

 Print the value of res with 6 decimal places using prin5.


Summary: The code solves a geometric problem using dynamic programming. It calculates the
minimum total cost of traversing a set of points with different possible skip counts while considering
penal es. The dynamic programming table dp is used to efficiently compute the minimum costs. The
code then selects the op mal path based on the total cost and penalty.

Code:

#include<bits/stdc++.h>

using namespace std;

using pi=pair<int,int>;

long double dist(pi a,pi b){

int dx=a.first-b.first;

int dy=a.second-b.second;

int ss=dx*dx+dy*dy;

return sqrt((long double)ss);

long double lg=8.0e18;

int main(){

int n;

cin >> n;

vector<pi> vp(n);

set<pi> st;

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

cin >> vp[i].first >> vp[i].second;

st.insert(vp[i]);

vector<vector<long double>> dp(n,vector<long double>(60,lg));

dp[0][0]=0.0;
for(int i=1;i<n;i++){

for(int j=i-1;j>=0;j--){

int skip=i-j-1;

for(int k=0;(k+skip)<60;k++){

dp[i][k+skip]=min(dp[i][k+skip],dp[j][k]+dist(vp[j],vp[i]));

long double res=lg;

for(int i=0;i<60;i++){

long double pen=0.0;

if(i>0){

pen=pow(2.0,(long double)(i-1));

res=min(res,dp[n-1][i]+pen);

prinC("%.6Lf\n",res);

return 0;

}
G - Ai + Bj + Ck = X (1 <= i, j, k <= N)  / 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 550 points

Problem Statement
You are given integers N , A, B, C, X . Find the number of triples of integers (i, j, k) that satisfy all of the
following conditions.

1 ≤ i, j, k ≤ N
Ai + Bj + Ck = X

Constraints
All input values are integers.
1 ≤ N ≤ 106
1 ≤ A, B, C ≤ 109
1 ≤ X ≤ 3 × 1015

Input
The input is given from Standard Input in the following format:

N A B C X

Output
Print the answer as an integer.

Sample Input 1  Copy

Copy
5 3 1 5 15

Sample Output 1  Copy

Copy
3

The following three triples satisfy the conditions.

(1, 2, 2) : 3 × 1 + 1 × 2 + 5 × 2 = 15
(2, 4, 1) : 3 × 2 + 1 × 4 + 5 × 1 = 15
(3, 1, 1) : 3 × 3 + 1 × 1 + 5 × 1 = 15
Sample Input 2  Copy

Copy
1 1 1 1 1

Sample Output 2  Copy

Copy
0

Sample Input 3  Copy

Copy
100000 31415 92653 58979 1000000000

Sample Output 3  Copy

Copy
2896
Algorithm:

Step 1: Template Func on extgcd This part of the code defines an extended greatest common divisor
(extgcd) template func on. This func on computes the greatest common divisor of two numbers a
and b, and simultaneously finds coefficients x and y that sa sfy the equa on ax+by=extgcd(a,b).

Step 2: llceil and llfloor Func ons These func ons calculate the ceiling and floor division of two
integers a and b. They return the smallest integer x such that x×b is greater than or equal to a (llceil)
and the largest integer x such that x×b is less than or equal to a (llfloor).

Step 3: findseg Func on This func on takes a pair of integers represen ng a segment
(seg.first,seg.second)(seg.first,seg.second), an ini al value ini, and a step value step. It calculates a new
segment that represents the possible range of values for the variable a'er applying the step. The result
considers both the ceiling and floor divisions of the segment boundaries.

Main Program

 The main program starts by reading the values of n, a, b, c, and x.

 It then adjusts the value of x by subtrac ng a+b+c. The purpose of this is to work with a
modified variable x in the following calcula ons.

 If x becomes nega ve a'er the adjustment, the output is "0" since there can't be any valid
solu ons in that case.

 The variable gbc is calculated as the greatest common divisor of b and c.

 The program ini alizes the variable res to count the number of valid triplets.

 The program iterates over possible values of i from 00 to n−1.

 It calculates rx as x−a×i.

 If rx becomes nega ve, it breaks the loop since further increasing i would only make
rx more nega ve.

 The program checks whether rx is divisible by gbc (the common divisor of b and c).

 If rx is not divisible by gbc, the program con nues to the next itera on.

 If rx is divisible by gbc, the program uses the extgcd func on to calculate possible
values of j and k that sa sfy b×j+c×k=rx. The calculated values are then used to
determine valid ranges for j and k using the findseg func on.

 The program calculates the intersec on of valid ranges for j and k to find the range of
values for which the triplet (i,j,k) is valid.

 If the intersec on range is non-empty (i.e., fr−fl+1>0), the count fr−fl+1 is added to
res.

 Finally, the program prints the value of res as the output.

Summary: The code solves a specific problem involving modular linear equa ons and coun ng valid
triplets that sa sfy certain condi ons. It employs mathema cal concepts like modular arithme c,
greatest common divisors, and linear Diophan ne equa ons. The approach is based on itera ng over
one variable and calcula ng valid ranges for the other two variables to count the solu ons.
Code:

#include<bits/stdc++.h>

using namespace std;

// h7ps://math.stackexchange.com/ques ons/670405/does-the-extended-euclidean-algorithm-
always-return-the-smallest-coefficients-of

// h7ps://teratail.com/ques ons/176282

// h7ps://ei1333.github.io/luzhiled/snippets/math/extgcd.html

template< typename T >

T extgcd(T a, T b, T &x, T &y) {

T d = a;

if(b != 0) {

d = extgcd(b, a % b, y, x);

y -= (a / b) * x;

} else {

x = 1;

y = 0;

return d;

long long llceil(long long a,long long b){

if(a%b==0){return a/b;}

if(a>=0){return (a/b)+1;}

else{return -((-a)/b);}

long long llfloor(long long a,long long b){


if(a%b==0){return a/b;}

if(a>=0){return (a/b);}

else{return -((-a)/b)-1;}

using pl=pair<long long,long long>;

pl findseg(pl seg,long long ini,long long step){

if(step>0){

return {llceil(seg.first-ini,step), llfloor(seg.second-ini,step)};

else{

step*=-1;

return {llceil(ini-seg.second,step), llfloor(ini-seg.first,step)};

int main(){

long long n,a,b,c,x;

cin >> n >> a >> b >> c >> x;

// 0 <= i,j,k < n

x -= (a+b+c);

if(x<0){cout << "0\n";return 0;}

long long res=0;

long long gbc=gcd(b,c);

long long stepj=(c/gbc);

long long stepk=-(b/gbc);


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

long long rx = x-a*i;

if(rx<0){break;}

// b*j + c*k = rx

if(rx%gbc){con nue;}

long long j,k;

extgcd(b,c,j,k);

j*=((rx%b)/gbc);

k*=((rx%b)/gbc);

long long jadd=(rx/b);

j+=jadd;

pl sj=findseg({0,n-1},j,stepj);

pl sk=findseg({0,n-1},k,stepk);

long long fl=max(sj.first,sk.first);

long long fr=min(sj.second,sk.second);

res+=max(0ll,fr-fl+1);

cout << res << "\n";

return 0;

}
Ex - Typical Convolution Problem  / 

Time Limit: 5 sec / Memory Limit: 1024 MB

Score : 650 points

Problem Statement
You are given a sequence (A1 , A2 , … , AN ). Let us define a sequence (F0 , F1 , … , FN ) by the
​ ​ ​ ​ ​ ​

following formulae.

F0 = 1 ​

Fn = An ∑ Fi Fj  (1 ≤ n ≤ N )
​ ​ ​ ​ ​

i+j<n

Find F1 , … , FN  modulo 998244353.
​ ​

Constraints
1 ≤ N ≤ 2 × 105
0 ≤ Ai < 998244353 ​

All input values are integers.

Input
The input is given from Standard Input in the following format:

N
A1 A2 … AN
​ ​ ​

Output
Print F1 , … , FN  modulo 998244353 in this order, with spaces in between.
​ ​

Sample Input 1  Copy

Copy
5
1 2 3 4 5

Sample Output 1  Copy

Copy
1 6 48 496 6240
F1 = A1 F0 F0 = 1. F2 = A2 (F0 F0 + F0 F1 + F1 F0 ) = 6. Similarly, we find F3 = 48, F4 = 496, F5 =
​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​

6240.

Sample Input 2  Copy

Copy
3
12345 678901 2345678

Sample Output 2  Copy

Copy
12345 790834943 85679169
Algorithm:

The provided problem seems to be an implementa on of polynomial mul plica on using the Fast
Fourier Transform (FFT) technique in a prime field modulo p=998244353. The algorithm is designed to
mul ply two polynomials f and g of arbitrary degree efficiently by u lizing the FFT algorithm for
polynomial mul plica on.

Here's a breakdown of the key components and the algorithm steps:

1. Ini aliza on: Ini alize the prime p=998244353, generator g=3, and its inverse ig=332748118.
Compute W and iW arrays to store powers of g and ig, respec vely.

2. FFT and IFFT Func ons: The ‘ ’ and ‘i ’ func ons implement the FFT and inverse FFT
algorithms, respec vely. These func ons perform the Fast Fourier Transform and its inverse
on the input array f.

3. Convolu on Func on: The convolve func on performs polynomial convolu on using FFT. If
the lengths of the input polynomials a and b are smaller than a threshold value (50 in this
case), it performs a direct polynomial mul plica on using nested loops. Otherwise, it uses FFT
to compute the convolu on efficiently.

4. Relaxed Mul plica on Class: The RelaxedMul plica on class encapsulates the process of
mul plying two polynomials in a relaxed manner. The class maintains arrays for f, g, and h,
represen ng the input polynomials and their product, respec vely. The append method
appends a new polynomial to the arrays and calculates the updated product polynomial. The
calc method calculates the convolu on between segments of f and g and accumulates the
result in h.

5. Main Program: The main program reads an integer n followed by n integers represen ng the
coefficients of polynomial f. It ini alizes a RelaxedMul plica on instance and computes arrays
F and G using the algorithm. The computed array F represents the coefficients of the
polynomial f mul plied by an auxiliary polynomial G. The result F is then printed.

This algorithm is quite advanced and involves concepts from both number theory (modular arithme c
and prime fields) and signal processing (FFT). It's used for efficient mul plica on of
polynomials in certain situa ons, par cularly in the context of computer algebra systems and
certain mathema cal algorithms. Keep in mind that this code assumes a deep understanding
of the FFT algorithm and modular arithme c. If you're planning to use or modify this code,
ensure that you thoroughly understand these concepts.

Detailed Step by Step Explana on of Algorithm:

Step 1: Ini aliza on

 Ini alize the prime p=998244353, which is used as the modulo for arithme c opera ons.

 Set g=3, which is a primi ve root modulo p.

 Calculate the inverse of g modulo p and store it as ig=332748118.

 Compute arrays W and iW to store powers of g and ig respec vely, using bitwise right shi7
(division by 2) and modulo p opera ons.

Step 2: FFT and IFFT Func ons


 Implement the func on that takes an array f and performs the Fast Fourier Transform on it
using the Bu9erfly FFT algorithm.

 Loop over different levels of FFT stages, denoted by l ranging from k down to 1.

 Calculate d, the distance between elements in each bu9erfly group for the current
stage.

 Calculate the powers of W required for the current stage and store them in the array
U.

 Iterate over the bu9erfly groups and update the elements of the array f using FFT
formulas involving W.

 Implement the i func on that takes an array f and performs the Inverse Fast Fourier
Transform on it.

 Similar to the func on, loop over different levels of IFFT stages.

 Calculate the powers of iW required for the current stage and store them in the array
U.

 Iterate over the bu9erfly groups and update the elements of the array f using IFFT
formulas involving iW.

Step 3: Convolu on Func on

 Implement the convolve func on that calculates the convolu on of two input arrays a and b
using FFT.

 Calculate the length of the resul ng convolu on array n0=len(a)+len(b)−1.

 If either a or b is small (e.g., both have lengths less than 50), perform a direct
convolu on using nested loops.

 Otherwise, calculate k, the smallest power of 2 greater than or equal to 0n0.

 Pad the input arrays a and b with zeros to a length of n, where n=2k.

 Apply the FFT to both a and b.

 Mul ply corresponding elements of a and b element-wise in the frequency domain.

 Apply the IFFT to the result and adjust for the scaling factor by mul plying with
pow(n,p−2,p).

Step 4: Relaxed Mul plica on Class

 Implement the RelaxedMul plica on class that handles the mul plica on of polynomials in
a relaxed manner.

 The class maintains arrays f, g, and h to store the input polynomials and the product
polynomial.

 The append method adds a new polynomial to the arrays and calculates the updated product
polynomial h using the calc method.
 The calc method calculates the convolu on between segments of f and g and accumulates the
result in the array h.

 The RelaxedMul plica on class is designed to handle polynomial mul plica on efficiently by
exploi ng the proper es of FFT.

Step 5: Main Program

 Read an integer n represen ng the degree of the polynomial.

 Read n integers represen ng the coefficients of polynomial f.

 Ini alize a RelaxedMul plica on instance as rel_mul.

 Ini alize arrays F and G with the first element 1, which will be used to store intermediate
results.

 Loop through the coefficients of polynomial f and perform the following for each coefficient
ai:

 Calculate the next element of G using the rel_mul.append method.

 Calculate the next element of F as ai × last element of Gmodp.

 Print the coefficients of polynomial F excluding the first element.

Summary: This algorithm efficiently mul plies polynomials using FFT techniques and takes advantage
of the relaxed mul plica on proper es. The code's structure revolves around FFT for
polynomial mul plica on and maintains auxiliary arrays to track intermediate results. It's
important to have a solid understanding of FFT, modular arithme c, and polynomial
opera ons to comprehend and use this algorithm effec vely.

Code:

P = 998244353

p, g, ig = 998244353, 3, 332748118

W = [pow(g, (p - 1) >> i, p) for i in range(24)]

iW = [pow(ig, (p - 1) >> i, p) for i in range(24)]

def convolve(a, b):

def K(f):

for l in range(k, 0, -1):

d = 1 << l - 1

U = [1]

for i in range(d):
U.append(U[-1] * W[l] % p)

for i in range(1 << k - l):

for j in range(d):

s=i*2*d+j

t=s+d

f[s], f[t] = (f[s] + f[t]) % p, U[j] * (f[s] - f[t]) % p

def iK(f):

for l in range(1, k + 1):

d = 1 << l - 1

U = [1]

for i in range(d):

U.append(U[-1] * iW[l] % p)

for i in range(1 << k - l):

for j in range(d):

s=i*2*d+j

t=s+d

f[s], f[t] = (f[s] + f[t] * U[j]) % p, (f[s] - f[t] * U[j]) % p

n0 = len(a) + len(b) - 1

if len(a) < 50 or len(b) < 50:

ret = [0] * n0

if len(a) > len(b): a, b = b, a

for i, aa in enumerate(a):

for j, bb in enumerate(b):

ret[i+j] = (ret[i+j] + aa * bb) % p

return ret

k = (n0).bit_length()
n = 1 << k

a = a + [0] * (n - len(a))

b = b + [0] * (n - len(b))

K(a), K(b)

for i in range(n):

a[i] = a[i] * b[i] % p

iK(a)

invn = pow(n, p - 2, p)

for i in range(n0):

a[i] = a[i] * invn % p

del a[n0:]

return a

class RelaxedMul plica on():

#h=f*g

def __init__(self):

self.f = []

self.g = []

self.h = []

self.n = 0

def calc(self, l1, r1, l2, r2):

self.h += [0] * (r1 + r2 - 1 - len(self.h))

for i, a in enumerate(convolve(self.f[l1:r1], self.g[l2:r2]), l1 + l2):

self.h[i] = (self.h[i] + a) % p

def append(self, a, b):

self.f.append(a)

self.g.append(b)

self.n += 1

n = self.n
m = (n + 1) & -(n + 1)

s=0

if m <= n:

a=1

while a <= m:

self.calc(n - a, n, s, s + a)

self.calc(s, s + a, n - a, n)

s += a

a <<= 1

else:

a=1

while a < m >> 1:

self.calc(n - a, n, s, s + a)

self.calc(s, s + a, n - a, n)

s += a

a <<= 1

self.calc(n - a, n, s, s + a)

return self.h[n-1]

n = input()

a = list(map(int, input().split()))

rel_mul = RelaxedMul plica on()

F = [1]

G = [rel_mul.append(1, 1)]

for ai in a:

F.append(ai * G[-1] % P)

G.append(G[-1] + rel_mul.append(F[-1], F[-1]))

print(" ".join(map(str, F[1:])))


THANK YOU

You might also like