A - 369
Problem Statement
You are given two integers
A
A
A and
B
B
B.
How many integers
x
x
x satisfy the following condition?
Condition: It is possible to arrange the three integers
A
A
A,
B
B
B, and
x
x
x in some order to form an arithmetic sequence.
A sequence of three integers
p
p
p,
q
q
q, and
r
r
r in this order is an arithmetic sequence if and only if
q
−
p
q-p
q−p is equal to
r
−
q
r-q
r−q.
Constraints
1
≤
A
,
B
≤
100
1 \leq A,B \leq 100
1≤A,B≤100
All input values are integers.
Input
The input is given from Standard Input in the following format:
A A A B B B
Output
Print the number of integers
x
x
x that satisfy the condition in the problem statement.
It can be proved that the answer is finite.
Sample Input 1
5 7
Sample Output 1
3
The integers
x
=
3
,
6
,
9
x=3,6,9
x=3,6,9 all satisfy the condition as follows:
When
x
=
3
x=3
x=3, for example, arranging
x
,
A
,
B
x,A,B
x,A,B forms the arithmetic sequence
3
,
5
,
7
3,5,7
3,5,7.
When
x
=
6
x=6
x=6, for example, arranging
B
,
x
,
A
B,x,A
B,x,A forms the arithmetic sequence
7
,
6
,
5
7,6,5
7,6,5.
When
x
=
9
x=9
x=9, for example, arranging
A
,
B
,
x
A,B,x
A,B,x forms the arithmetic sequence
5
,
7
,
9
5,7,9
5,7,9.
Conversely, there are no other values of
x
x
x that satisfy the condition.
Therefore, the answer is
3
3
3.
Sample Input 2
6 1
Sample Output 2
2
Only x = − 4 x=-4 x=−4 and 11 11 11 satisfy the condition.
Sample Input 3
3 3
Sample Output 3
1
Only x = 3 x=3 x=3 satisfies the condition.
Solution
具体见文末视频。
Code
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int a, b;
cin >> a >> b;
if (a > b) swap(a, b);
set<int> S;
if ((a + b) % 2 == 0) S.insert(a + b >> 1);
S.insert(b + b - a), S.insert(a - (b - a));
cout << S.size() << endl;
return 0;
}
B - Piano 3
Problem Statement
Takahashi has a piano with
100
100
100 keys arranged in a row.
The
i
i
i-th key from the left is called key
i
i
i.
He will play music by pressing
N
N
N keys one by one.
For the
i
i
i-th press, he will press key
A
i
A_i
Ai, using his left hand if
S
i
=
S_i=
Si= L
, and his right hand if
S
i
=
S_i=
Si= R
.
Before starting to play, he can place both of his hands on any keys he likes, and his fatigue level at this point is 0.
During the performance, if he moves one hand from key
x
x
x to key
y
y
y, the fatigue level increases by
∣
y
−
x
∣
|y-x|
∣y−x∣ (conversely, the fatigue level does not increase for any reason other than moving hands).
To press a certain key with a hand, that hand must be placed on that key.
Find the minimum possible fatigue level at the end of the performance.
Constraints
1
≤
N
≤
100
1 \leq N \leq 100
1≤N≤100
1
≤
A
i
≤
100
1 \leq A_i \leq 100
1≤Ai≤100
N
N
N and
A
i
A_i
Ai are integers.
S
i
S_i
Si is L
or R
.
Input
The input is given from Standard Input in the following format:
N
N
N
A
1
A_1
A1
S
1
S_1
S1
A
2
A_2
A2
S
2
S_2
S2
⋮
\vdots
⋮
A
N
A_N
AN
S
N
S_N
SN
Output
Print the minimum fatigue level at the end of the performance.
Sample Input 1
4
3 L
6 R
9 L
1 R
Sample Output 1
11
For example, the performance can be done as follows:
Initially, place the left hand on key
3
3
3 and the right hand on key
6
6
6.
Press key
3
3
3 with the left hand.
Press key
6
6
6 with the right hand.
Move the left hand from key
3
3
3 to key
9
9
9. The fatigue level increases by
∣
9
−
3
∣
=
6
|9-3| = 6
∣9−3∣=6.
Move the right hand from key
6
6
6 to key
1
1
1. The fatigue level increases by
∣
1
−
6
∣
=
5
|1-6| = 5
∣1−6∣=5.
Press key
9
9
9 with the left hand.
Press key
1
1
1 with the right hand.
In this case, the fatigue level at the end of the performance is
6
+
5
=
11
6+5 = 11
6+5=11, which is the minimum possible.
Sample Input 2
3
2 L
2 L
100 L
Sample Output 2
98
Sample Input 3
8
22 L
75 L
26 R
45 R
72 R
81 R
47 L
29 R
Sample Output 3
188
Solution
具体见文末视频。
Code
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int n;
cin >> n;
std::vector<int> a(n);
std::vector<char> s(n);
for (int i = 0; i < n; i ++)
cin >> a[i] >> s[i];
int res = 1e18;
for (int i = 1; i <= 100; i ++)
for (int j = 1; j <= 100; j ++) {
int lo = i, ro = j, ans = 0;
for (int k = 0; k < n; k ++) {
if (s[k] == 'L') ans += abs(a[k] - lo), lo = a[k];
else ans += abs(a[k] - ro), ro = a[k];
}
res = min(res, ans);
}
cout << res << endl;
return 0;
}
C - Count Arithmetic Subarrays
Problem Statement
You are given a sequence of
N
N
N positive integers
A
=
(
A
1
,
A
2
,
…
,
A
N
)
A=(A_1,A_2,\dots,A_N)
A=(A1,A2,…,AN).
Find the number of pairs of integers
(
l
,
r
)
(l,r)
(l,r) satisfying
1
≤
l
≤
r
≤
N
1\leq l\leq r\leq N
1≤l≤r≤N such that the subsequence
(
A
l
,
A
l
+
1
,
…
,
A
r
)
(A_l,A_{l+1},\dots,A_r)
(Al,Al+1,…,Ar) forms an arithmetic progression.
A sequence
(
x
1
,
x
2
,
…
,
x
∣
x
∣
)
(x_1,x_2,\dots,x_{|x|})
(x1,x2,…,x∣x∣) is an arithmetic progression if and only if there exists a
d
d
d such that KaTeX parse error: Expected 'EOF', got '&' at position 25: …_i=d\ (1\leq i &̲lt; |x|).
In particular, a sequence of length
1
1
1 is always an arithmetic progression.
Constraints
1
≤
N
≤
2
×
1
0
5
1\leq N \leq 2\times 10^5
1≤N≤2×105
1
≤
A
i
≤
1
0
9
1\leq A_i \leq 10^9
1≤Ai≤109
All input values are integers.
Input
The input is given from Standard Input in the following format:
N
N
N
A
1
A_1
A1
A
2
A_2
A2
…
\dots
…
A
N
A_N
AN
Output
Print the answer.
Sample Input 1
4
3 6 9 3
Sample Output 1
8
There are eight pairs of integers
(
l
,
r
)
(l,r)
(l,r) satisfying the condition:
(
1
,
1
)
,
(
2
,
2
)
,
(
3
,
3
)
,
(
4
,
4
)
,
(
1
,
2
)
,
(
2
,
3
)
,
(
3
,
4
)
,
(
1
,
3
)
(1,1),(2,2),(3,3),(4,4),(1,2),(2,3),(3,4),(1,3)
(1,1),(2,2),(3,3),(4,4),(1,2),(2,3),(3,4),(1,3).
Indeed, when
(
l
,
r
)
=
(
1
,
3
)
(l,r)=(1,3)
(l,r)=(1,3),
(
A
l
,
…
,
A
r
)
=
(
3
,
6
,
9
)
(A_l,\dots,A_r)=(3,6,9)
(Al,…,Ar)=(3,6,9) is an arithmetic progression, so it satisfies the condition.
However, when
(
l
,
r
)
=
(
2
,
4
)
(l,r)=(2,4)
(l,r)=(2,4),
(
A
l
,
…
,
A
r
)
=
(
6
,
9
,
3
)
(A_l,\dots,A_r)=(6,9,3)
(Al,…,Ar)=(6,9,3) is not an arithmetic progression, so it does not satisfy the condition.
Sample Input 2
5
1 1 1 1 1
Sample Output 2
15
All pairs of integers ( l , r ) ( 1 ≤ l ≤ r ≤ 5 ) (l,r)\ (1\leq l\leq r\leq 5) (l,r) (1≤l≤r≤5) satisfy the condition.
Sample Input 3
8
87 42 64 86 72 58 44 30
Sample Output 3
22
Solution
具体见文末视频。
Code
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int n;
cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; i ++)
cin >> a[i];
int len = 2, res = 0;
for (int i = 2; i < n; i ++)
if (a[i] - a[i - 1] == a[i - 1] - a[i - 2]) len ++;
else res += (len - 1) * (len - 2) / 2, len = 2;
res += (len - 1) * (len - 2) / 2;
cout << res + n - 1 + n << endl;
return 0;
}
D - Bonus EXP
Problem Statement
Takahashi will encounter
N
N
N monsters in order. The
i
i
i-th monster
(
1
≤
i
≤
N
)
(1\leq i\leq N)
(1≤i≤N) has a strength of
A
i
A_i
Ai.
For each monster, he can choose to either let it go or defeat it.
Each action awards him experience points as follows:
If he lets a monster go, he gains
0
0
0 experience points.
If he defeats a monster with strength
X
X
X, he gains
X
X
X experience points.
If it is an even-numbered defeated monster (2nd, 4th, …), he gains an additional
X
X
X experience points.
Find the maximum total experience points he can gain from the
N
N
N monsters.
Constraints
1
≤
N
≤
2
×
1
0
5
1\leq N\leq 2\times 10^5
1≤N≤2×105
1
≤
A
i
≤
1
0
9
1\leq A_i\leq 10^9
1≤Ai≤109
All input values are integers.
Input
The input is given from Standard Input in the following format:
N
N
N
A
1
A_1
A1
A
2
A_2
A2
…
\ldots
…
A
N
A_N
AN
Output
Print the maximum total experience points he can gain from the N N N monsters as an integer.
Sample Input 1
5
1 5 3 2 7
Sample Output 1
28
If Takahashi defeats the 1st, 2nd, 3rd, and 5th monsters, and lets the 4th monster go, he gains experience points as follows:
Defeats a monster with strength
A
1
=
1
A_1=1
A1=1. He gains
1
1
1 experience point.
Defeats a monster with strength
A
2
=
5
A_2=5
A2=5. He gains
5
5
5 experience points. As it is the 2nd defeated monster, he gains an additional
5
5
5 points.
Defeats a monster with strength
A
3
=
3
A_3=3
A3=3. He gains
3
3
3 experience points.
Lets the 4th monster go. Takahashi gains no experience points.
Defeats a monster with strength
A
5
=
7
A_5=7
A5=7. He gains
7
7
7 experience points. As it is the 4th defeated monster, he gains an additional
7
7
7 points.
Therefore, in this case, he gains
1
+
(
5
+
5
)
+
3
+
0
+
(
7
+
7
)
=
28
1+(5+5)+3+0+(7+7)=28
1+(5+5)+3+0+(7+7)=28 experience points.
Note that even if he encounters a monster, if he lets it go, it does not count as defeated.
He can gain at most
28
28
28 experience points no matter how he acts, so print
28
28
28.
As a side note, if he defeats all monsters in this case, he would gain
1
+
(
5
+
5
)
+
3
+
(
2
+
2
)
+
7
=
25
1+(5+5)+3+(2+2)+7=25
1+(5+5)+3+(2+2)+7=25 experience points.
Sample Input 2
2
1000000000 1000000000
Sample Output 2
3000000000
Beware that the answer may not fit in a 32 32 32-bit integer.
Solution
具体见文末视频。
Code
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int n;
cin >> n;
const int inf = 1e18;
std::vector<int> a(n + 1);
std::vector<vector<int>> dp(n + 1, vector<int>(2, -inf));
for (int i = 1; i <= n; i ++)
cin >> a[i];
dp[0][0] = 0;
for (int i = 1; i <= n; i ++)
for (int j = 0; j < 2; j ++) {
if (!j) dp[i][j] = max(dp[i - 1][j], dp[i - 1][j ^ 1] + a[i] * 2);
else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j ^ 1] + a[i]);
}
cout << max(dp[n][0], dp[n][1]) << endl;
return 0;
}
E - Sightseeing Tour
Problem Statement
There are
N
N
N islands and
M
M
M bidirectional bridges connecting two islands. The islands and bridges are numbered
1
1
1,
2
2
2,
…
\ldots
…,
N
N
N and
1
1
1,
2
2
2,
…
\ldots
…,
M
M
M, respectively.
Bridge
i
i
i connects islands
U
i
U_i
Ui and
V
i
V_i
Vi, and the time it takes to cross it in either direction is
T
i
T_i
Ti.
No bridge connects an island to itself, but it is possible for two islands to be directly connected by more than one bridge.
One can travel between any two islands using some bridges.
You are given
Q
Q
Q queries, so answer each of them. The
i
i
i-th query is as follows:
You are given $K_i$ distinct bridges: bridges $B_{i,1}, B_{i,2}, \ldots, B_{i,K_i}$.## Constraints
Find the minimum time required to travel from island $1$ to island $N$ using each of these bridges at least once.
Only consider the time spent crossing bridges.
You can cross the given bridges in any order and in any direction.
2
≤
N
≤
400
2 \leq N \leq 400
2≤N≤400
N
−
1
≤
M
≤
2
×
1
0
5
N-1 \leq M \leq 2 \times 10^5
N−1≤M≤2×105
KaTeX parse error: Expected 'EOF', got '&' at position 12: 1 \leq U_i &̲lt; V_i \leq N
1
≤
T
i
≤
1
0
9
1 \leq T_i \leq 10^9
1≤Ti≤109
1
≤
Q
≤
3000
1 \leq Q \leq 3000
1≤Q≤3000
1
≤
K
i
≤
5
1 \leq K_i \leq 5
1≤Ki≤5
KaTeX parse error: Expected 'EOF', got '&' at position 16: 1 \leq B_{i,1} &̲lt; B_{i,2} <…
All input values are integers.
It is possible to travel between any two islands using some bridges.
Input
The input is given from Standard Input in the following format:
N
N
N
M
M
M
U
1
U_1
U1
V
1
V_1
V1
T
1
T_1
T1
U
2
U_2
U2
V
2
V_2
V2
T
2
T_2
T2
⋮
\vdots
⋮
U
M
U_M
UM
V
M
V_M
VM
T
M
T_M
TM
Q
Q
Q
K
1
K_1
K1
B
1
,
1
B_{1,1}
B1,1
B
1
,
2
B_{1,2}
B1,2
⋯
\cdots
⋯
B
1
,
K
1
B_{1,{K_1}}
B1,K1
K
2
K_2
K2
B
2
,
1
B_{2,1}
B2,1
B
2
,
2
B_{2,2}
B2,2
⋯
\cdots
⋯
B
2
,
K
2
B_{2,{K_2}}
B2,K2
⋮
\vdots
⋮
K
Q
K_Q
KQ
B
Q
,
1
B_{Q,1}
BQ,1
B
Q
,
2
B_{Q,2}
BQ,2
⋯
\cdots
⋯
B
Q
,
K
Q
B_{Q,{K_Q}}
BQ,KQ
Output
Print Q Q Q lines. The i i i-th line ( 1 ≤ i ≤ Q 1 \leq i \leq Q 1≤i≤Q) should contain the answer to the i i i-th query as an integer.
Sample Input 1
3 5
1 2 10
1 3 20
1 3 30
2 3 15
2 3 25
2
1
1
2
3 5
Sample Output 1
25
70
For the first query, we need to find the minimum time to travel from island
1
1
1 to island
3
3
3 while using bridge
1
1
1.
The minimum time is achieved by using bridge
1
1
1 to move from island
1
1
1 to island
2
2
2, then using bridge
4
4
4 to move from island
2
2
2 to island
3
3
3. The time taken is
10
+
15
=
25
10 + 15 = 25
10+15=25.
Hence, print
25
25
25 on the first line.
For the second query, we need to find the minimum time to travel from island
1
1
1 to island
3
3
3 while using both bridges
3
3
3 and
5
5
5.
The minimum time is achieved by using bridge
3
3
3 to move from island
1
1
1 to island
3
3
3, then using bridge
5
5
5 to move to island
2
2
2, and finally using bridge
4
4
4 to return to island
3
3
3. The time taken is
30
+
25
+
15
=
70
30 + 25 + 15 = 70
30+25+15=70.
Hence, print
70
70
70 on the second line.
Sample Input 2
6 6
1 5 1
2 5 1
2 4 1
3 4 1
3 6 1
1 6 1
2
5
1 2 3 4 5
1
5
Sample Output 2
5
3
For each query, you can cross the specified bridges in either direction.
Sample Input 3
5 5
1 2 1000000000
2 3 1000000000
3 4 1000000000
4 5 1000000000
1 5 1000000000
1
1
3
Sample Output 3
4000000000
Beware that the answer may not fit in a 32 32 32-bit integer.
Solution
具体见文末视频。
Code
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int N = 4e2 + 10, M = 2e5 + 10;
int n, m, q;
int g[N][N], E[M][2], w[M];
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> n >> m;
memset(g, 0x3f, sizeof g);
for (int i = 1; i <= n; i ++) g[i][i] = 0;
for (int i = 1; i <= m; i ++) {
int a, b, c;
cin >> a >> b >> c, E[i][0] = a, E[i][1] = b, w[i] = c;
g[a][b] = g[b][a] = min(g[a][b], c);
}
for (int k = 1; k <= n; k ++)
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= n; j ++)
g[i][j] = min(g[i][k] + g[k][j], g[i][j]);
cin >> q;
while (q -- ) {
int len;
cin >> len;
std::vector<int> b(len + 1);
int more = 0;
for (int i = 1; i <= len; i ++) cin >> b[i], more += w[b[i]];
int res = 1e18;
do {
for (int i = 0; i < 1 << len; i ++) {
int cost = 0;
cost += g[1][E[b[1]][i & 1]] + g[E[b[len]][((i >> len - 1) & 1) ^ 1]][n];
for (int j = 1; j < len; j ++)
cost += g[E[b[j]][((i >> j - 1) & 1) ^ 1]][E[b[j + 1]][i >> j & 1]];
res = min(res, cost);
}
}while (next_permutation(b.begin() + 1, b.end()));
cout << res + more << endl;
}
return 0;
}
F - Gather Coins
Problem Statement
There is a grid with
H
H
H rows and
W
W
W columns.
Let
(
i
,
j
)
(i,j)
(i,j) denote the cell at the
i
i
i-th row from the top and
j
j
j-th column from the left.
There are
N
N
N coins on this grid, and the
i
i
i-th coin can be picked up by passing through the cell
(
R
i
,
C
i
)
(R_i,C_i)
(Ri,Ci).
Your goal is to start from cell
(
1
,
1
)
(1,1)
(1,1), repeatedly move either down or right by one cell, and reach cell
(
H
,
W
)
(H,W)
(H,W) while picking up as many coins as possible.
Find the maximum number of coins you can pick up and one of the paths that achieves this maximum.
Constraints
2
≤
H
,
W
≤
2
×
1
0
5
2\leq H,W \leq 2\times 10^5
2≤H,W≤2×105
1
≤
N
≤
min
(
H
W
−
2
,
2
×
1
0
5
)
1\leq N \leq \min(HW-2, 2\times 10^5)
1≤N≤min(HW−2,2×105)
1
≤
R
i
≤
H
1\leq R_i \leq H
1≤Ri≤H
1
≤
C
i
≤
W
1\leq C_i \leq W
1≤Ci≤W
(
R
i
,
C
i
)
≠
(
1
,
1
)
(R_i,C_i)\neq (1,1)
(Ri,Ci)=(1,1)
(
R
i
,
C
i
)
≠
(
H
,
W
)
(R_i,C_i)\neq (H,W)
(Ri,Ci)=(H,W)
(
R
i
,
C
i
)
(R_i,C_i)
(Ri,Ci) are pairwise distinct.
All input values are integers.
Input
The input is given from Standard Input in the following format:
$H$ $W$ $N$
$R_1$ $C_1$
$R_2$ $C_2$
$\vdots$
$R_N$ $C_N$
Output
Print two lines.
The first line should contain the maximum number of coins you can pick up.
The second line should contain one of the paths that achieves this maximum as a string of length
H
+
W
−
2
H+W-2
H+W−2.
The
i
i
i-th character of this string should be D
if the
i
i
i-th move is downward, and R
if it is rightward.
If there are multiple paths that maximize the number of coins picked up, you may print any of them.
Sample Input 1
3 4 4
3 3
2 1
2 3
1 4
Sample Output 1
3
DRRDR
As shown in the figure above, by moving ( 1 , 1 ) → ( 2 , 1 ) → ( 2 , 2 ) → ( 2 , 3 ) → ( 3 , 3 ) → ( 3 , 4 ) (1,1)\rightarrow (2,1)\rightarrow (2,2)\rightarrow (2,3)\rightarrow (3,3)\rightarrow (3,4) (1,1)→(2,1)→(2,2)→(2,3)→(3,3)→(3,4), you can pick up three coins at ( 2 , 1 ) , ( 2 , 3 ) , ( 3 , 3 ) (2,1),(2,3),(3,3) (2,1),(2,3),(3,3).
Sample Input 2
2 2 2
2 1
1 2
Sample Output 2
1
DR
The path RD
is also acceptable.
Sample Input 3
10 15 8
2 7
2 9
7 9
10 3
7 11
8 12
9 6
8 1
Sample Output 3
5
DRRRRRRRRDDDDDRRDRDDRRR
Solution
具体见文末视频。
Code
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int inf = 1e18;
struct info {
int mx, idx;
info(int _mx, int _idx): mx(_mx), idx(_idx) {}
};
info operator+ (info a, info b) {
info c(-inf, 0);
if (a.mx > b.mx) c.mx = a.mx, c.idx = a.idx;
else c.mx = b.mx, c.idx = b.idx;
return c;
}
struct fenwick {
vector<info> tr;
fenwick() {}
fenwick(info x, int n) { init(x, n); }
void init(info x, int n) { tr.resize(n + 1, x); }
void add(int x, info d) {
for (int i = x; i < tr.size(); i += (i & -i)) tr[i] = tr[i] + d;
}
info sum(int x) {
if (!x) return info(-inf, 0);
info res = info(-inf, 0);
for (int i = x; i; i -= (i & -i)) res = res + tr[i];
return res;
}
};
const int N = 2e5 + 10;
int h, w, n;
PII pnt[N];
int dp[N], pre[N];
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> h >> w >> n;
pnt[1] = {1, 1}, pnt[n + 2] = {h, w};
for (int i = 2; i <= n + 1; i ++)
cin >> pnt[i].fi >> pnt[i].se;
sort(pnt + 1, pnt + 1 + n + 2);
fenwick mx(info(-inf, 0), w);
dp[1] = 0, mx.add(1, info(0, 1));
for (int i = 2; i <= n + 2; i ++) {
dp[i] = mx.sum(pnt[i].se).mx + (i != n + 2);
pre[i] = mx.sum(pnt[i].se).idx, mx.add(pnt[i].se, info(dp[i], i));
}
cout << dp[n + 2] << endl;
int lst = n + 2;
std::vector<int> way;
while (pre[lst])
way.push_back(lst), lst = pre[lst];
way.push_back(lst);
reverse(way.begin(), way.end());
for (int i = 1; i < way.size(); i ++) {
for (int j = 1; j <= abs(pnt[way[i]].fi - pnt[way[i - 1]].fi); j ++)
cout << 'D';
for (int j = 1; j <= abs(pnt[way[i]].se - pnt[way[i - 1]].se); j ++)
cout << 'R';
}
cout << endl;
return 0;
}
G - As far as possible
Problem Statement
You are given a tree with
N
N
N vertices.
The vertices are numbered
1
1
1,
2
2
2,
…
\ldots
…,
N
N
N.
The
i
i
i-th edge (
1
≤
i
≤
N
−
1
1\leq i\leq N-1
1≤i≤N−1) connects vertices
U
i
U_i
Ui and
V
i
V_i
Vi, with a length of
L
i
L_i
Li.
For each
K
=
1
,
2
,
…
,
N
K=1,2,\ldots, N
K=1,2,…,N, solve the following problem.
Takahashi and Aoki play a game. The game proceeds as follows. First, Aoki specifies $K$ distinct vertices on the tree. Then, Takahashi constructs a walk that starts and ends at vertex $1$, and passes through all the vertices specified by Aoki. The score is defined as the length of the walk constructed by Takahashi. Takahashi wants to minimize the score, while Aoki wants to maximize it. Find the score when both players play optimally.Definition of a walk A walk on an undirected graph (possibly a tree) is a sequence of $k$ vertices and $k-1$ edges $v_1,e_1,v_2,\ldots,v_{k-1},e_{k-1},v_k$ (where $k$ is a positive integer) such that edge $e_i$ connects vertices $v_i$ and $v_{i+1}$. The same vertex or edge can appear multiple times in the sequence. A walk is said to pass through vertex $x$ if there exists at least one $i$ ($1\leq i\leq k$) such that $v_i=x$. (There can be multiple such $i$.) The walk is said to start and end at $v_1$ and $v_k$, respectively, and the length of the walk is the sum of the lengths of $e_1$, $e_2$, $\ldots$, $e_{k-1}$. ## Constraints
2
≤
N
≤
2
×
1
0
5
2\leq N\leq 2\times 10^5
2≤N≤2×105
KaTeX parse error: Expected 'EOF', got '&' at position 10: 1\leq U_i&̲lt;V_i\leq N
1
≤
L
i
≤
1
0
9
1\leq L_i\leq 10^9
1≤Li≤109
All input values are integers.
The given graph is a tree.
Input
The input is given from Standard Input in the following format:
N
N
N
U
1
U_1
U1
V
1
V_1
V1
L
1
L_1
L1
U
2
U_2
U2
V
2
V_2
V2
L
2
L_2
L2
⋮
\vdots
⋮
U
N
−
1
U_{N-1}
UN−1
V
N
−
1
V_{N-1}
VN−1
L
N
−
1
L_{N-1}
LN−1
Output
Print
N
N
N lines.
The
i
i
i-th line
(
1
≤
i
≤
N
)
(1\leq i\leq N)
(1≤i≤N) should contain the answer to the problem for
K
=
i
K=i
K=i.
Sample Input 1
5
1 2 3
2 3 5
2 4 2
1 5 3
Sample Output 1
16
22
26
26
26
For
K
=
1
K=1
K=1, Aoki’s optimal move is to specify vertex
3
3
3, and Takahashi’s optimal move is to construct a path vertex
1
1
1
→
\to
→ vertex
2
2
2
→
\to
→ vertex
3
3
3
→
\to
→ vertex
2
2
2
→
\to
→ vertex
1
1
1, resulting in a score of
16
16
16.
For
K
=
2
K=2
K=2, Aoki’s optimal move is to specify vertices
3
3
3 and
5
5
5, and Takahashi’s optimal move is to construct a path such as vertex
1
1
1
→
\to
→ vertex
5
5
5
→
\to
→ vertex
1
1
1
→
\to
→ vertex
2
2
2
→
\to
→ vertex
3
3
3
→
\to
→ vertex
2
2
2
→
\to
→ vertex
1
1
1, resulting in a score of
22
22
22.
For
K
≥
3
K\geq 3
K≥3, the score when both players play optimally is
26
26
26.
Sample Input 2
3
1 2 1000000000
2 3 1000000000
Sample Output 2
4000000000
4000000000
4000000000
Beware that the answer may not fit in a 32 32 32-bit integer.
Solution
具体见文末视频。
Code
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int N = 2e5 + 10, M = 4e5 + 10;
int n;
int h[N], e[M], ne[M], w[M], idx;
int dep[N], fa[N][20], d[N], pre[N], nxt[N], res[N], val[N], dis[N];
std::vector<int> leaf;
void add(int a, int b, int c) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;
}
void dfs(int u, int par) {
if (d[u] == 1) leaf.push_back(u);
for (int i = 1; i < 20; i ++) fa[u][i] = fa[fa[u][i - 1]][i - 1];
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
if (v == par) continue;
dep[v] = dep[u] + 1, dis[v] = dis[u] + w[i], fa[v][0] = u;
dfs(v, u);
}
}
int lca(int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
for (int i = 19; i >= 0; i --)
if (dep[fa[u][i]] >= dep[v]) u = fa[u][i];
if (u == v) return u;
for (int i = 19; i >= 0; i --)
if (fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i];
return fa[u][0];
}
int dist(int u, int v) {
return dis[u] + dis[v] - 2 * dis[lca(u, v)];
}
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> n;
memset(h, -1, sizeof h);
for (int i = 1; i < n; i ++) {
int u, v, l;
cin >> u >> v >> l;
add(u, v, l), add(v, u, l), d[u] ++, d[v] ++;
}
dfs(1, -1);
pre[leaf[0]] = 1;
for (int i = 1; i < leaf.size(); i ++)
pre[leaf[i]] = leaf[i - 1], nxt[leaf[i - 1]] = leaf[i];
nxt[leaf.back()] = 1;
set<PII> S;
for (auto v : leaf) {
val[v] = -(dist(pre[v], nxt[v]) - dist(pre[v], v) - dist(v, nxt[v]));
S.insert({val[v], v}), res[leaf.size()] += dist(pre[v], v);
}
res[leaf.size()] += dist(leaf.back(), 1);
// for (auto v : S)
// cout << v.fi << " " << v.se << endl;
int tot = leaf.size();
while (S.size()) {
auto tmp = *S.begin();
S.erase(S.begin()), tot --;
res[tot] = res[tot + 1] - tmp.fi;
nxt[pre[tmp.se]] = nxt[tmp.se];
pre[nxt[tmp.se]] = pre[tmp.se];
if (pre[tmp.se] != 1) {
int v = pre[tmp.se];
S.erase({val[v], v});
val[v] = -(dist(pre[v], nxt[v]) - dist(pre[v], v) - dist(v, nxt[v]));
S.insert({val[v], v});
} if (nxt[tmp.se] != 1) {
int v = nxt[tmp.se];
S.erase({val[v], v});
val[v] = -(dist(pre[v], nxt[v]) - dist(pre[v], v) - dist(v, nxt[v]));
S.insert({val[v], v});
}
}
for (int i = 1; i <= n; i ++) {
if (i <= leaf.size()) cout << res[i] << endl;
else cout << res[leaf.size()] << endl;
}
return 0;
}
视频题解
AtCoder Beginner Contest 369(A ~ G 题讲解)
最后祝大家早日