A - Count Takahashi
Problem Statement
You are given N N N strings.
The i i i-th string S i S_i Si ( 1 ≤ i ≤ N ) (1 \leq i \leq N) (1≤i≤N) is either Takahashi
or Aoki
.
How many i i i are there such that S i S_i Si is equal to Takahashi
?
Constraints
1 ≤ N ≤ 100 1 \leq N \leq 100 1≤N≤100
N N N is an integer.
Each S i S_i Si is Takahashi
or Aoki
. ( 1 ≤ i ≤ N ) (1 \leq i \leq N) (1≤i≤N)
Input
The input is given from Standard Input in the following format:
N N N
S 1 S_1 S1
S 2 S_2 S2
⋮ \vdots ⋮
S N S_N SN
Output
Print the count of i i i such that S i S_i Si is equal to Takahashi
as an integer in a single line.
Sample Input 1
3
Aoki
Takahashi
Takahashi
Sample Output 1
2
S 2 S_2 S2 and S 3 S_3 S3 are equal to Takahashi
, while S 1 S_1 S1 is not.
Therefore, print 2
.
Sample Input 2
2
Aoki
Aoki
Sample Output 2
0
It is possible that no S i S_i Si is equal to Takahashi
.
Sample Input 3
20
Aoki
Takahashi
Takahashi
Aoki
Aoki
Aoki
Aoki
Takahashi
Aoki
Aoki
Aoki
Takahashi
Takahashi
Aoki
Takahashi
Aoki
Aoki
Aoki
Aoki
Takahashi
Sample Output 3
7
Solution
具体见文末视频。
Code
cpp
#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;
int res = 0;
for (int i = 1; i <= n; i ++) {
string s;
cin >> s;
if (s == "Takahashi") res ++;
}
cout << res << endl;
return 0;
}
B - Couples
Problem Statement
There are 2 N 2N 2N people standing in a row, and the person at the i i i-th position from the left is wearing clothes of color A i A_i Ai. Here, the clothes have N N N colors from 1 1 1 to N N N, and exactly two people are wearing clothes of each color.
Find how many of the integers i = 1 , 2 , ... , N i=1,2,\ldots,N i=1,2,...,N satisfy the following condition:
There is exactly one person between the two people wearing clothes of color i i i.
Constraints
2 ≤ N ≤ 100 2 \leq N \leq 100 2≤N≤100
1 ≤ A i ≤ N 1 \leq A_i \leq N 1≤Ai≤N
Each integer from 1 1 1 through N N N appears exactly twice in A A A.
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 2 N A_{2N} A2N
Output
Print the answer.
Sample Input 1
3
1 2 1 3 2 3
Sample Output 1
2
There are two values of i i i that satisfy the condition: 1 1 1 and 3 3 3.
In fact, the people wearing clothes of color 1 1 1 are at the 1st and 3rd positions from the left, with exactly one person in between.
Sample Input 2
2
1 1 2 2
Sample Output 2
0
There may be no i i i that satisfies the condition.
Sample Input 3
4
4 3 2 3 2 1 4 1
Sample Output 3
3
Solution
具体见文末视频。
Code
cpp
#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(2 * n);
for (int i = 0; i < 2 * n; i ++)
cin >> a[i];
int res = 0;
for (int i = 1; i < 2 * n - 1; i ++)
if (a[i - 1] == a[i + 1])
res ++;
cout << res << endl;
return 0;
}
C - Tile Distance 2
Problem Statement
The coordinate plane is covered with 2 × 1 2\times1 2×1 tiles. The tiles are laid out according to the following rules:
For an integer pair ( i , j ) (i,j) (i,j), the square A i , j = { ( x , y ) ∣ i ≤ x ≤ i + 1 ∧ j ≤ y ≤ j + 1 } A _ {i,j}=\lbrace(x,y)\mid i\leq x\leq i+1\wedge j\leq y\leq j+1\rbrace Ai,j={(x,y)∣i≤x≤i+1∧j≤y≤j+1} is contained in one tile.
When i + j i+j i+j is even, A i , j A _ {i,j} Ai,j and A i + 1 , j A _ {i + 1,j} Ai+1,j are contained in the same tile.
Tiles include their boundaries, and no two different tiles share a positive area.
Near the origin, the tiles are laid out as follows:
Takahashi starts at the point ( S x + 0.5 , S y + 0.5 ) (S _ x+0.5,S _ y+0.5) (Sx+0.5,Sy+0.5) on the coordinate plane.
He can repeat the following move as many times as he likes:
Choose a direction (up, down, left, or right) and a positive integer n n n. Move n n n units in that direction.
Each time he enters a tile, he pays a toll of 1 1 1.
Find the minimum toll he must pay to reach the point ( T x + 0.5 , T y + 0.5 ) (T _ x+0.5,T _ y+0.5) (Tx+0.5,Ty+0.5).
Constraints
0 ≤ S x ≤ 2 × 1 0 16 0\leq S _ x\leq2\times10 ^ {16} 0≤Sx≤2×1016
0 ≤ S y ≤ 2 × 1 0 16 0\leq S _ y\leq2\times10 ^ {16} 0≤Sy≤2×1016
0 ≤ T x ≤ 2 × 1 0 16 0\leq T _ x\leq2\times10 ^ {16} 0≤Tx≤2×1016
0 ≤ T y ≤ 2 × 1 0 16 0\leq T _ y\leq2\times10 ^ {16} 0≤Ty≤2×1016
All input values are integers.
Input
The input is given from Standard Input in the following format:
S x S _ x Sx S y S _ y Sy
T x T _ x Tx T y T _ y Ty
Output
Print the minimum toll Takahashi must pay.
Sample Input 1
5 0
2 5
Sample Output 1
5
For example, Takahashi can pay a toll of 5 5 5 by moving as follows:
Move left by 1 1 1. Pay a toll of 0 0 0.
Move up by 1 1 1. Pay a toll of 1 1 1.
Move left by 1 1 1. Pay a toll of 0 0 0.
Move up by 3 3 3. Pay a toll of 3 3 3.
Move left by 1 1 1. Pay a toll of 0 0 0.
Move up by 1 1 1. Pay a toll of 1 1 1.
It is impossible to reduce the toll to 4 4 4 or less, so print 5
.
Sample Input 2
3 1
4 1
Sample Output 2
0
There are cases where no toll needs to be paid.
Sample Input 3
2552608206527595 5411232866732612
771856005518028 7206210729152763
Sample Output 3
1794977862420151
Note that the value to be output may exceed the range of a 32 32 32-bit integer.
Solution
具体见文末视频。
Code
cpp
#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 sx, sy, fx, fy;
cin >> sx >> sy >> fx >> fy;
int res = abs(sy - fy);
if ((sx + sy & 1) && fx < sx || ((sx + sy) % 2 == 0) && fx > sx) {
res += max(0ll, abs(sx - fx) - abs(sy - fy) >> 1);
} else {
res += max(0ll, abs(sx - fx) - abs(sy - fy) + 1 >> 1);
}
cout << res << endl;
return 0;
}
D - Avoid K Palindrome
Problem Statement
You are given a string S S S of length N N N consisting of characters A
, B
, and ?
.
You are also given a positive integer K K K.
A string T T T consisting of A
and B
is considered a good string if it satisfies the following condition:
No contiguous substring of length K K K in T T T is a palindrome.
Let q q q be the number of ?
characters in S S S.
There are 2 q 2^q 2q strings that can be obtained by replacing each ?
in S S S with either A
or B
. Find how many of these strings are good strings.
The count can be very large, so find it modulo 998244353 998244353 998244353.
Constraints
2 ≤ K ≤ N ≤ 1000 2 \leq K \leq N \leq 1000 2≤K≤N≤1000
K ≤ 10 K \leq 10 K≤10
S S S is a string consisting of A
, B
, and ?
.
The length of S S S is N N N.
N N N and K K K are integers.
Input
The input is given from Standard Input in the following format:
N N N K K K
S S S
Output
Print the answer.
Sample Input 1
7 4
AB?A?BA
Sample Output 1
1
The given string has two ?
s.
There are four strings obtained by replacing each ?
with A
or B
:
ABAAABA
ABAABBA
ABBAABA
ABBABBA
Among these, the last three contain the contiguous substring ABBA
of length 4, which is a palindrome, and thus are not good strings.
Therefore, you should print 1
.
Sample Input 2
40 7
????????????????????????????????????????
Sample Output 2
116295436
Ensure to find the number of good strings modulo 998244353 998244353 998244353.
Sample Input 3
15 5
ABABA??????????
Sample Output 3
0
It is possible that there is no way to replace the ?
s to obtain a good string.
Sample Input 4
40 8
?A?B??B?B?AA?A?B??B?A???B?BB?B???BA??BAA
Sample Output 4
259240
Solution
具体见文末视频。
Code
cpp
#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 = 1e3 + 10, M = 11, mod = 998244353;
int n, k;
string s;
int f[N][1 << M];
bool check(int x) {
string a, b;
for (int i = 0; i < k; i ++)
a += char((x >> i & 1) ^ 48);
b = a;
reverse(b.begin(), b.end());
return a != b;
}
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> n >> k >> s;
s = ' ' + s;
std::vector<int> avl;
avl.push_back(0);
for (int i = 1; i <= k; i ++) {
std::vector<int> ok;
while (avl.size()) {
int tmp = avl.back();
avl.pop_back();
if (s[i] == '?') {
ok.push_back(tmp), ok.push_back(tmp | (1ll << i - 1));
} else if (s[i] == 'B') {
ok.push_back(tmp | (1ll << i - 1));
} else {
ok.push_back(tmp);
}
}
avl = ok;
}
for (auto v : avl)
if (check(v))
f[k][v] = 1;
for (int i = k + 1; i <= n; i ++)
for (int j = 0; j < 1ll << k; j ++)
if (s[i] == '?') {
if (check(j) && check(j >> 1)) f[i][j >> 1] = (f[i][j >> 1] + f[i - 1][j]) % mod;
if (check(j) && check((j >> 1) | (1ll << k - 1))) f[i][(j >> 1) | (1ll << k - 1)] = (f[i][(j >> 1) | (1ll << k - 1)] + f[i - 1][j]) % mod;
} else if (s[i] == 'B') {
if (check(j) && check((j >> 1) | (1ll << k - 1))) f[i][(j >> 1) | (1ll << k - 1)] = (f[i][(j >> 1) | (1ll << k - 1)] + f[i - 1][j]) % mod;
} else {
if (check(j) && check(j >> 1)) f[i][j >> 1] = (f[i][j >> 1] + f[i - 1][j]) % mod;
}
int res = 0;
for (int i = 0; i < 1ll << k; i ++)
res = (res + f[n][i]) % mod;
cout << res << endl;
return 0;
}
E - Water Tank
Problem Statement
You are given a sequence of positive integers of length N N N: H = ( H 1 , H 2 , ... , H N ) H=(H _ 1,H _ 2,\dotsc,H _ N) H=(H1,H2,...,HN).
There is a sequence of non-negative integers of length N + 1 N+1 N+1: A = ( A 0 , A 1 , ... , A N ) A=(A _ 0,A _ 1,\dotsc,A _ N) A=(A0,A1,...,AN). Initially, A 0 = A 1 = ⋯ = A N = 0 A _ 0=A _ 1=\dotsb=A _ N=0 A0=A1=⋯=AN=0.
Perform the following operations repeatedly on A A A:
- Increase the value of A _ 0 by 1. For i=1,2,\\ldots,N in this order, perform the following operation: If A _ {i-1}\\gt A _ i and A _ {i-1}\\gt H _ i, decrease the value of A _ {i-1} by 1 and increase the value of A _ i by 1.
For each i=1,2,\\ldots,N, find the number of operations before A _ i\>0 holds for the first time. ## Constraints
1 ≤ N ≤ 2 × 1 0 5 1\leq N\leq2\times10 ^ 5 1≤N≤2×105
1 ≤ H i ≤ 1 0 9 ( 1 ≤ i ≤ N ) 1\leq H _ i\leq10 ^ 9\ (1\leq i\leq N) 1≤Hi≤109 (1≤i≤N)
All input values are integers.
Input
The input is given from Standard Input in the following format:
N N N
H 1 H _ 1 H1 H 2 H _ 2 H2 ... \dotsc ... H N H _ N HN
Output
Print the answers for i = 1 , 2 , ... , N i=1,2,\ldots,N i=1,2,...,N in a single line, separated by spaces.
Sample Input 1
5
3 1 4 1 5
Sample Output 1
4 5 13 14 26
The first five operations go as follows.
Here, each row corresponds to one operation, with the leftmost column representing step 1 and the others representing step 2.
From this diagram, A 1 > 0 A _ 1\gt0 A1>0 holds for the first time after the 4th operation, and A 2 > 0 A _ 2\gt0 A2>0 holds for the first time after the 5th operation.
Similarly, the answers for A 3 , A 4 , A 5 A _ 3, A _ 4, A _ 5 A3,A4,A5 are 13 , 14 , 26 13, 14, 26 13,14,26, respectively.
Therefore, you should print 4 5 13 14 26
.
Sample Input 2
6
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000
Sample Output 2
1000000001 2000000001 3000000001 4000000001 5000000001 6000000001
Note that the values to be output may not fit within a 32 32 32-bit integer.
Sample Input 3
15
748 169 586 329 972 529 432 519 408 587 138 249 656 114 632
Sample Output 3
749 918 1921 2250 4861 5390 5822 6428 6836 7796 7934 8294 10109 10223 11373
Solution
具体见文末视频。
Code
cpp
#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;
int n;
int a[N], to[N], f[N];
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> n;
stack<int> stk;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
while (stk.size() && a[stk.top()] < a[i]) stk.pop();
if (stk.size()) to[i] = stk.top();
stk.push(i);
}
for (int i = 1; i <= n; i ++)
f[i] = f[to[i]] + (i - to[i]) * a[i], cout << f[i] + 1 << " ";
return 0;
}
F - Tree Degree Optimization
Problem Statement
You are given a sequence of integers A = ( A 1 , ... , A N ) A=(A_1,\ldots,A_N) A=(A1,...,AN). For a tree T T T with N N N vertices, define f ( T ) f(T) f(T) as follows:
Let d i d_i di be the degree of vertex i i i in T T T. Then, f ( T ) = ∑ i = 1 N d i 2 A i f(T)=\sum_{i=1}^N {d_i}^2 A_i f(T)=∑i=1Ndi2Ai.
Find the minimum possible value of f ( T ) f(T) f(T).
The constraints guarantee the answer to be less than 2 63 2^{63} 263.
Constraints
2 ≤ N ≤ 2 × 1 0 5 2\leq N\leq 2\times 10^5 2≤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 answer.
Sample Input 1
4
3 2 5 2
Sample Output 1
24
Consider a tree T T T with an edge connecting vertices 1 1 1 and 2 2 2, an edge connecting vertices 2 2 2 and 4 4 4, and an edge connecting vertices 4 4 4 and 3 3 3.
Then, f ( T ) = 1 2 × 3 + 2 2 × 2 + 1 2 × 5 + 2 2 × 2 = 24 f(T) = 1^2\times 3 + 2^2\times 2 + 1^2\times 5 + 2^2\times 2 = 24 f(T)=12×3+22×2+12×5+22×2=24. It can be proven that this is the minimum value of f ( T ) f(T) f(T).
Sample Input 2
3
4 3 2
Sample Output 2
15
Sample Input 3
7
10 5 10 2 10 13 15
Sample Output 3
128
Solution
具体见文末视频。
Code
cpp
#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;
int n;
int a[N], d[N];
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> n;
for (int i = 1; i <= n; i ++)
cin >> a[i];
priority_queue<PII, vector<PII>, greater<PII>> heap;
for (int i = 1; i <= n; i ++)
d[i] = 1, heap.push({a[i] * (2 * d[i] + 1), i});
for (int i = 1; i <= n - 2; i ++) {
auto tmp = heap.top(); heap.pop();
d[tmp.se] ++, heap.push({a[tmp.se] * (2 * d[tmp.se] + 1), tmp.se});
}
int res = 0;
for (int i = 1; i <= n; i ++) res += d[i] * d[i] * a[i];
cout << res << endl;
return 0;
}
G - Sum of Tree Distance
Problem Statement
You are given a tree with N N N vertices. The i i i-th edge connects vertices u i u_i ui and v i v_i vi bidirectionally.
Additionally, you are given an integer sequence A = ( A 1 , ... , A N ) A=(A_1,\ldots,A_N) A=(A1,...,AN).
Here, define f ( i , j ) f(i,j) f(i,j) as follows:
If A i = A j A_i = A_j Ai=Aj, then f ( i , j ) f(i,j) f(i,j) is the minimum number of edges you need to traverse to move from vertex i i i to vertex j j j. If A i ≠ A j A_i \neq A_j Ai=Aj, then f ( i , j ) = 0 f(i,j) = 0 f(i,j)=0.
Calculate the value of the following expression:
\\displaystyle \\sum_{i=1}\^{N-1}\\sum_{j=i+1}\^N f(i,j).
Constraints
2 ≤ N ≤ 2 × 1 0 5 2 \leq N \leq 2 \times 10^5 2≤N≤2×105
1 ≤ u i , v i ≤ N 1 \leq u_i, v_i \leq N 1≤ui,vi≤N
1 ≤ A i ≤ N 1 \leq A_i \leq N 1≤Ai≤N
The input graph is a tree.
All input values are integers.
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
⋮ \vdots ⋮
u N − 1 u_{N-1} uN−1 v N − 1 v_{N-1} vN−1
A 1 A_1 A1 A 2 A_2 A2 ... \ldots ... A N A_N AN
Output
Print the answer.
Sample Input 1
4
3 4
4 2
1 2
2 1 1 2
Sample Output 1
4
f ( 1 , 4 ) = 2 , f ( 2 , 3 ) = 2 f(1,4)=2, f(2,3)=2 f(1,4)=2,f(2,3)=2. For all other KaTeX parse error: Expected 'EOF', got '&' at position 17: ..., j\ (1 \leq i &̲lt; j \leq N), we have f ( i , j ) = 0 f(i,j)=0 f(i,j)=0, so the answer is 2 + 2 = 4 2+2=4 2+2=4.
Sample Input 2
8
8 6
3 8
1 4
7 8
4 5
3 4
8 2
1 2 2 2 3 1 1 3
Sample Output 2
19
Solution
具体见文末视频。
Code
cpp
#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, B = 448;
int n;
int a[N], dep[N], idx[N], tot[N], cnt[N], acl[N][B + 10], id[N];
int f[N << 1][20], Euler[N << 1], pl[N], m, sub;
std::vector<int> g[N], pos[N], big;
void dfs(int u, int fa) {
Euler[ ++ m] = u, pl[u] = m;
for (auto v : g[u]) {
if (v == fa) continue;
dep[v] = dep[u] + 1;
dfs(v, u), Euler[ ++ m] = u;
}
}
void dfs2(int u, int fa) {
if (id[a[u]]) acl[u][id[a[u]]] ++;
for (auto v : g[u]) {
if (v == fa) continue;
dfs2(v, u);
for (auto i : big) acl[u][i] += acl[v][i];
}
for (auto i : big) {
int sum = 0, res = 0;
for (auto v : g[u]) {
if (v == fa) continue;
res += acl[v][i] * sum, sum += acl[v][i];
}
sub += res * dep[u] * 2;
}
if (id[a[u]]) sub += (acl[u][id[a[u]]] - 1) * dep[u] * 2;
}
void build() {
for (int j = 0; j <= log2(m); j ++)
for (int i = 1; i + (1ll << j) - 1 <= m; i ++)
if (!j) f[i][j] = i;
else {
if (dep[Euler[f[i][j - 1]]] < dep[Euler[f[i + (1ll << j - 1)][j - 1]]]) f[i][j] = f[i][j - 1];
else f[i][j] = f[i + (1ll << j - 1)][j - 1];
}
}
int query(int l, int r) {
int k = log2(r - l + 1);
if (dep[Euler[f[l][k]]] < dep[Euler[f[r - (1ll << k) + 1][k]]]) return f[l][k];
return f[r - (1ll << k) + 1][k];
}
int lca(int a, int b) {
if (pl[a] > pl[b]) swap(a, b);
return Euler[query(pl[a], pl[b])];
}
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> n;
for (int i = 1; i < n; i ++) {
int u, v;
cin >> u >> v;
g[u].push_back(v), g[v].push_back(u);
}
for (int i = 1; i <= n; i ++)
cin >> a[i], pos[a[i]].push_back(i);
dfs(1, -1), build();
int res1 = 0, res2 = 0, tmp = 0;
for (int i = 1; i <= n; i ++) {
if (pos[a[i]].size() <= B) {
for (int j = 0; j < idx[a[i]]; j ++)
res2 += dep[lca(i, pos[a[i]][j])] * 2;
idx[a[i]] ++;
} else if (!id[a[i]]) id[a[i]] = ++ tmp, big.push_back(tmp);
res1 += tot[a[i]] + cnt[a[i]] * dep[i];
tot[a[i]] += dep[i], cnt[a[i]] ++;
}
dfs2(1, -1);
cout << res1 - res2 - sub << endl;
return 0;
}
视频题解
AtCoder Beginner Contest 359(A ~ G 题讲解)
最后祝大家早日