A - TLD
Problem Statement
You are given a string
S
S
S consisting of lowercase English letters and the character .
.
Print the last substring when
S
S
S is split by .
s.
In other words, print the longest suffix of
S
S
S that does not contain .
.
Constraints
S
S
S is a string of length between
2
2
2 and
100
100
100, inclusive, consisting of lowercase English letters and .
.
S
S
S contains at least one .
.
S
S
S does not end with .
.
Input
The input is given from Standard Input in the following format:
S S S
Output
Print the answer.
Sample Input 1
atcoder.jp
Sample Output 1
jp
The longest suffix of atcoder.jp
that does not contain .
is jp
.
Sample Input 2
translate.google.com
Sample Output 2
com
S
S
S may contain multiple .
s.
Sample Input 3
.z
Sample Output 3
z
S
S
S may start with .
.
Sample Input 4
..........txt
Sample Output 4
txt
S
S
S may contain consecutive .
s.
Solution
具体见文末视频。
Code
#include <bits/stdc++.h>
#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);
string S;
cin >> S;
int N = S.size();
string Result;
S = ' ' + S;
while (S[N] != '.')
Result += S[N], N --;
reverse(Result.begin(), Result.end());
cout << Result << endl;
return 0;
}
B - Langton’s Takahashi
Problem Statement
There is a grid with
H
H
H rows and
W
W
W columns; initially, all cells are painted white. Let
(
i
,
j
)
(i, j)
(i,j) denote the cell at the
i
i
i-th row from the top and the
j
j
j-th column from the left.
This grid is considered to be toroidal. That is,
(
i
,
1
)
(i, 1)
(i,1) is to the right of
(
i
,
W
)
(i, W)
(i,W) for each
1
≤
i
≤
H
1 \leq i \leq H
1≤i≤H, and
(
1
,
j
)
(1, j)
(1,j) is below
(
H
,
j
)
(H, j)
(H,j) for each
1
≤
j
≤
W
1 \leq j \leq W
1≤j≤W.
Takahashi is at
(
1
,
1
)
(1, 1)
(1,1) and facing upwards. Print the color of each cell in the grid after Takahashi repeats the following operation
N
N
N times.
If the current cell is painted white, repaint it black, rotate
9
0
∘
90^\circ
90∘ clockwise, and move forward one cell in the direction he is facing. Otherwise, repaint the current cell white, rotate
9
0
∘
90^\circ
90∘ counterclockwise, and move forward one cell in the direction he is facing.
Constraints
1
≤
H
,
W
≤
100
1 \leq H, W \leq 100
1≤H,W≤100
1
≤
N
≤
1000
1 \leq N \leq 1000
1≤N≤1000
All input values are integers.
Input
The input is given from Standard Input in the following format:
H H H W W W N N N
Output
Print
H
H
H lines. The
i
i
i-th line should contain a string of length
W
W
W where the
j
j
j-th character is .
if the cell
(
i
,
j
)
(i, j)
(i,j) is painted white, and #
if it is painted black.
Sample Input 1
3 4 5
Sample Output 1
.#..
##..
....
The cells of the grid change as follows due to the operations:
.... #... ##.. ##.. ##.. .#..
.... → .... → .... → .#.. → ##.. → ##..
.... .... .... .... .... ....
Sample Input 2
2 2 1000
Sample Output 2
..
..
Sample Input 3
10 10 10
Sample Output 3
##........
##........
..........
..........
..........
..........
..........
..........
..........
#........#
Solution
具体见文末视频。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int SIZE = 1e2 + 10;
int H, W, N;
char Result[SIZE][SIZE];
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
signed main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> H >> W >> N;
for (int i = 1; i <= H; i ++)
for (int j = 1; j <= W; j ++)
Result[i][j] = '.';
int X = 1, Y = 1, Sd = 0;
for (int i = 1; i <= N; i ++)
if (Result[X][Y] == '.')
{
Result[X][Y] = '#';
Sd = (Sd + 1) % 4;
X += dx[Sd], Y += dy[Sd];
X = (X + H) % H, Y = (Y + W) % W;
if (!X) X = H;
if (!Y) Y = W;
}
else
{
Result[X][Y] = '.';
Sd = (Sd + 3) % 4;
X += dx[Sd], Y += dy[Sd];
X = (X + H) % H, Y = (Y + W) % W;
if (!X) X = H;
if (!Y) Y = W;
}
for (int i = 1; i <= H; i ++)
{
for (int j = 1; j <= W; j ++)
cout << Result[i][j];
cout << endl;
}
return 0;
}
C - Perfect Bus
Problem Statement
A bus is in operation. The number of passengers on the bus is always a non-negative integer.
At some point in time, the bus had zero or more passengers, and it has stopped
N
N
N times since then. At the
i
i
i-th stop, the number of passengers increased by
A
i
A_i
Ai. Here,
A
i
A_i
Ai can be negative, meaning the number of passengers decreased by
−
A
i
-A_i
−Ai. Also, no passengers got on or off the bus other than at the stops.
Find the minimum possible current number of passengers on the bus that is consistent with the given information.
Constraints
1
≤
N
≤
2
×
1
0
5
1 \leq N \leq 2 \times 10^5
1≤N≤2×105
−
1
0
9
≤
A
i
≤
1
0
9
-10^9 \leq A_i \leq 10^9
−109≤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 -5 7 -4
Sample Output 1
3
If the initial number of passengers was 2 2 2, the current number of passengers would be 2 + 3 + ( − 5 ) + 7 + ( − 4 ) = 3 2 + 3 + (-5) + 7 + (-4) = 3 2+3+(−5)+7+(−4)=3, and the number of passengers on the bus would have always been a non-negative integer.
Sample Input 2
5
0 0 0 0 0
Sample Output 2
0
Sample Input 3
4
-1 1000000000 1000000000 1000000000
Sample Output 3
3000000000
Solution
具体见文末视频。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int SIZE = 2e5 + 10;
int N;
int A[SIZE], S[SIZE];
signed main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> N;
int Min = 1e18;
for (int i = 1; i <= N; i ++)
cin >> A[i], S[i] = S[i - 1] + A[i], Min = min(Min, S[i]);
int Result = 0;
if (Min < 0) Result = -Min;
for (int i = 1; i <= N; i ++)
Result += A[i];
cout << Result << endl;
return 0;
}
D - Synchronized Players
Problem Statement
There is an
N
×
N
N \times N
N×N grid, where each cell is either empty or contains an obstacle. Let
(
i
,
j
)
(i, j)
(i,j) denote the cell at the
i
i
i-th row from the top and the
j
j
j-th column from the left.
There are also two players on distinct empty cells of the grid. The information about each cell is given as
N
N
N strings
S
1
,
S
2
,
…
,
S
N
S_1, S_2, \ldots, S_N
S1,S2,…,SN of length
N
N
N, in the following format:
If the
j
j
j-th character of
S
i
S_i
Si is P
, then
(
i
,
j
)
(i, j)
(i,j) is an empty cell with a player on it.
If the
j
j
j-th character of
S
i
S_i
Si is .
, then
(
i
,
j
)
(i, j)
(i,j) is an empty cell without a player.
If the
j
j
j-th character of
S
i
S_i
Si is #
, then
(
i
,
j
)
(i, j)
(i,j) contains an obstacle.
Find the minimum number of moves required to bring the two players to the same cell by repeating the following operation. If it is impossible to bring the two players to the same cell by repeating the operation, print -1
.
Choose one of the four directions: up, down, left, or right. Then, each player attempts to move to the adjacent cell in that direction. Each player moves if the destination cell exists and is empty, and does not move otherwise.
Constraints
N
N
N is an integer between
2
2
2 and
60
60
60, inclusive.
S
i
S_i
Si is a string of length
N
N
N consisting of P
, .
, and #
.
There are exactly two pairs
(
i
,
j
)
(i, j)
(i,j) where the
j
j
j-th character of
S
i
S_i
Si is P
.
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 answer.
Sample Input 1
5
....#
#..#.
.P...
..P..
....#
Sample Output 1
3
Let us call the player starting at
(
3
,
2
)
(3, 2)
(3,2) Player 1 and the player starting at
(
4
,
3
)
(4, 3)
(4,3) Player 2.
For example, doing the following brings the two players to the same cell in three moves:
Choose left. Player 1 moves to
(
3
,
1
)
(3, 1)
(3,1), and Player 2 moves to
(
4
,
2
)
(4, 2)
(4,2).
Choose up. Player 1 does not move, and Player 2 moves to
(
3
,
2
)
(3, 2)
(3,2).
Choose left. Player 1 does not move, and Player 2 moves to
(
3
,
1
)
(3, 1)
(3,1).
Sample Input 2
2
P#
#P
Sample Output 2
-1
Sample Input 3
10
..........
..........
..........
..........
....P.....
.....P....
..........
..........
..........
..........
Sample Output 3
10
Solution
具体见文末视频。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int SIZE = 65;
int N;
char Graph[SIZE][SIZE];
int Dist[SIZE][SIZE][SIZE][SIZE], Vis[SIZE][SIZE][SIZE][SIZE];
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
struct Node { int X1, Y1, X2, Y2; };
void BFS(int Sx, int Sy, int Sx2, int Sy2)
{
memset(Vis, 0, sizeof Vis);
memset(Dist, 0x3f, sizeof Dist);
queue<Node> Q;
Q.push({Sx, Sy, Sx2, Sy2});
Dist[Sx][Sy][Sx2][Sy2] = 0;
while (Q.size())
{
auto Tmp = Q.front();
Q.pop();
if (Vis[Tmp.X1][Tmp.Y1][Tmp.X2][Tmp.Y2]) continue;
Vis[Tmp.X1][Tmp.Y1][Tmp.X2][Tmp.Y2] = 1;
// cout << Tmp.X1 << " " << Tmp.Y1 << ' ' << Tmp.X2 << ' ' << Tmp.Y2 << endl;
for (int i = 0; i < 4; i ++)
{
int xx1 = Tmp.X1 + dx[i], yy1 = Tmp.Y1 + dy[i];
int xx2 = Tmp.X2 + dx[i], yy2 = Tmp.Y2 + dy[i];
xx1 = max(1ll, xx1), yy1 = max(1ll, yy1), xx1 = min(N, xx1), yy1 = min(N, yy1);
xx2 = max(1ll, xx2), yy2 = max(1ll, yy2), xx2 = min(N, xx2), yy2 = min(N, yy2);
if (Graph[xx1][yy1] == '#') xx1 = Tmp.X1, yy1 = Tmp.Y1;
if (Graph[xx2][yy2] == '#') xx2 = Tmp.X2, yy2 = Tmp.Y2;
Dist[xx1][yy1][xx2][yy2] = min(Dist[xx1][yy1][xx2][yy2], Dist[Tmp.X1][Tmp.Y1][Tmp.X2][Tmp.Y2] + 1);
Q.push({xx1, yy1, xx2, yy2});
}
}
}
signed main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> N;
int X1 = 0, Y1, X2, Y2;
for (int i = 1; i <= N; i ++)
for (int j = 1; j <= N; j ++)
{
cin >> Graph[i][j];
if (Graph[i][j] == 'P' && !X1) X1 = i, Y1 = j;
else if (Graph[i][j] == 'P') X2 = i, Y2 = j;
}
BFS(X1, Y1, X2, Y2);
int Result = 1e18;
for (int i = 1; i <= N; i ++)
for (int j = 1; j <= N; j ++)
Result = min(Result, Dist[i][j][i][j]);
if (Result == 1e18) cout << -1 << endl;
else cout << Result << endl;
return 0;
}
E - Smooth Subsequence
Problem Statement
You are given a sequence
A
=
(
A
1
,
A
2
,
…
,
A
N
)
A = (A_1, A_2, \ldots, A_N)
A=(A1,A2,…,AN) of length
N
N
N.
Find the maximum length of a subsequence of
A
A
A such that the absolute difference between any two adjacent terms is at most
D
D
D.
A subsequence of a sequence
A
A
A is a sequence that can be obtained by deleting zero or more elements from
A
A
A and arranging the remaining elements in their original order.
Constraints
1
≤
N
≤
5
×
1
0
5
1 \leq N \leq 5 \times 10^5
1≤N≤5×105
0
≤
D
≤
5
×
1
0
5
0 \leq D \leq 5 \times 10^5
0≤D≤5×105
1
≤
A
i
≤
5
×
1
0
5
1 \leq A_i \leq 5 \times 10^5
1≤Ai≤5×105
All input values are integers.
Input
The input is given from Standard Input in the following format:
N
N
N
D
D
D
A
1
A_1
A1
A
2
A_2
A2
…
\ldots
…
A
N
A_N
AN
Output
Print the answer.
Sample Input 1
4 2
3 5 1 2
Sample Output 1
3
The subsequence ( 3 , 1 , 2 ) (3, 1, 2) (3,1,2) of A A A has absolute differences of at most 2 2 2 between adjacent terms.
Sample Input 2
5 10
10 20 100 110 120
Sample Output 2
3
Sample Input 3
11 7
21 10 3 19 28 12 11 3 3 15 16
Sample Output 3
6
Solution
具体见文末视频。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int SIZE = 5e5 + 10;
int N, D;
int A[SIZE];
struct Segment
{
struct Node
{
int l, r;
LL Sum, Max, Min, Lazy;
}Tree[SIZE << 2];
void Pushup(int u)
{
Tree[u].Sum = Tree[u << 1].Sum + Tree[u << 1 | 1].Sum;
Tree[u].Max = max(Tree[u << 1].Max, Tree[u << 1 | 1].Max);
Tree[u].Min = min(Tree[u << 1].Min, Tree[u << 1 | 1].Min);
}
void Pushdown(int u)
{
if (Tree[u].Lazy)
{
Tree[u << 1].Max += Tree[u].Lazy;
Tree[u << 1].Min += Tree[u].Lazy;
Tree[u << 1].Sum += (LL)(Tree[u << 1].r - Tree[u << 1].l + 1) * Tree[u].Lazy;
Tree[u << 1].Lazy += Tree[u].Lazy;
Tree[u << 1 | 1].Max += Tree[u].Lazy;
Tree[u << 1 | 1].Min += Tree[u].Lazy;
Tree[u << 1 | 1].Sum += (LL)(Tree[u << 1 | 1].r - Tree[u << 1 | 1].l + 1) * Tree[u].Lazy;
Tree[u << 1 | 1].Lazy += Tree[u].Lazy;
Tree[u].Lazy = 0;
}
}
void Build(int u, int l, int r)
{
Tree[u] = {l, r};
if (l == r) return;
int mid = l + r >> 1;
Build(u << 1, l, mid), Build(u << 1 | 1, mid + 1, r);
}
void Modify(int u, int l, int r, int d)
{
if (Tree[u].l >= l && Tree[u].r <= r)
{
Tree[u].Sum += (LL)(Tree[u].r - Tree[u].l + 1) * d;
Tree[u].Max += d, Tree[u].Min += d;
Tree[u].Lazy += d;
return;
}
Pushdown(u);
int mid = Tree[u].l + Tree[u].r >> 1;
if (mid >= l) Modify(u << 1, l, r, d);
if (mid < r) Modify(u << 1 | 1, l, r, d);
Pushup(u);
}
int Query(int u, int l, int r, int k)
{
if (Tree[u].l >= l && Tree[u].r <= r)
{
if (k == 1) return Tree[u].Sum;
else if (k == 2) return Tree[u].Max;
else return Tree[u].Min;
}
Pushdown(u);
long long mid = Tree[u].l + Tree[u].r >> 1, Result;
if (k == 1) Result = 0;
else if (k == 2) Result = -1e18;
else Result = 1e18;
if (mid >= l) Result = Query(u << 1, l, r, k);
if (mid < r)
{
if (k == 1) Result += Query(u << 1 | 1, l, r, k);
else if (k == 2) Result = max(Result, Query(u << 1 | 1, l, r, k));
else Result = min(Result, Query(u << 1 | 1, l, r, k));
}
return Result;
}
int Sum(int l, int r) { return Query(1, l, r, 1); }
int Max(int l, int r) { return Query(1, l, r, 2); }
int Min(int l, int r) { return Query(1, l, r, 3); }
}Tool;
signed main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> N >> D;
int Mx = 0;
for (int i = 1; i <= N; i ++)
cin >> A[i], Mx = max(Mx, A[i]);
Tool.Build(1, 1, Mx);
Tool.Modify(1, A[1], A[1], 1);
for (int i = 2; i <= N; i ++)
Tool.Modify(1, A[i], A[i], Tool.Max(max(A[i] - D, 1ll), min(A[i] + D, Mx)) + 1 - Tool.Max(A[i], A[i]));
cout << Tool.Max(1, Mx) << endl;
return 0;
}
F - Product Equality
Problem Statement
You are given
N
N
N integers
A
1
,
A
2
,
…
,
A
N
A_1, A_2, \dots, A_N
A1,A2,…,AN.
Find the number of triples of integers
(
i
,
j
,
k
)
(i, j, k)
(i,j,k) that satisfy the following conditions:
1
≤
i
,
j
,
k
≤
N
1 \le i, j, k \le N
1≤i,j,k≤N
A
i
×
A
j
=
A
k
A_i \times A_j = A_k
Ai×Aj=Ak
Constraints
1
≤
N
≤
1000
1 \le N \le 1000
1≤N≤1000
KaTeX parse error: Expected '}', got '&' at position 23: …red}{1 \le A_i &̲lt; 10^{1000}}
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
⋮
\vdots
⋮
A
N
A_N
AN
Output
Print the answer as an integer.
Sample Input 1
5
2
3
6
12
24
Sample Output 1
6
The following six triples
(
i
,
j
,
k
)
(i, j, k)
(i,j,k) satisfy the conditions in the problem statement:
(
1
,
2
,
3
)
(1, 2, 3)
(1,2,3)
(
1
,
3
,
4
)
(1, 3, 4)
(1,3,4)
(
1
,
4
,
5
)
(1, 4, 5)
(1,4,5)
(
2
,
1
,
3
)
(2, 1, 3)
(2,1,3)
(
3
,
1
,
4
)
(3, 1, 4)
(3,1,4)
(
4
,
1
,
5
)
(4, 1, 5)
(4,1,5)
Sample Input 2
11
1
2
3
4
5
6
123456789123456789
123456789123456789
987654321987654321
987654321987654321
121932631356500531347203169112635269
Sample Output 2
40
Note that the values of each integer A i A_i Ai can be huge.
Sample Input 3
9
4
4
4
2
2
2
1
1
1
Sample Output 3
162
Note that there may be duplicates among the values of A i A_i Ai.
Solution
具体见文末视频。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int SIZE = 1e3 + 10, M1 = 998244353, M2 = 1e9 + 7, M3 = 1145141, M4 = 1e9 + 3;
int N;
int A[SIZE], B[SIZE], C[SIZE], D[SIZE];
map<int, map<int, map<int, map<int, int>>>> Cnt;
signed main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> N;
for (int i = 1; i <= N; i ++)
{
string S;
cin >> S;
for (int j = 0; j < S.size(); j ++)
{
A[i] = A[i] * 10 + S[j] - '0', B[i] = B[i] * 10 + S[j] - '0';
C[i] = C[i] * 10 + S[j] - '0', D[i] = D[i] * 10 + S[j] - '0';
A[i] %= M1, B[i] %= M2, C[i] %= M3, D[i] %= M4;
}
Cnt[A[i]][B[i]][C[i]][D[i]] ++;
}
int Result = 0;
for (int i = 1; i <= N; i ++)
for (int j = 1; j <= N; j ++)
Result += Cnt[A[i] * A[j] % M1][B[i] * B[j] % M2][C[i] * C[j] % M3][D[i] * D[j] % M4];
cout << Result << endl;
return 0;
}
G - Smaller Sum
Problem Statement
You are given a sequence
A
=
(
A
1
,
A
2
,
…
,
A
N
)
A=(A_1,A_2,\dots,A_N)
A=(A1,A2,…,AN) of length
N
N
N.
Answer the following
Q
Q
Q queries. The
i
i
i-th query is as follows:
Find the sum of the elements among
A
L
i
,
A
L
i
+
1
,
…
,
A
R
i
A_{L_i},A_{L_i+1},\dots,A_{R_i}
ALi,ALi+1,…,ARi that are not greater than
X
i
X_i
Xi.
Here, you need to answer these queries online.
That is, only after you answer the current query is the next query revealed.
For this reason, instead of the
i
i
i-th query itself, you are given encrypted inputs
α
i
,
β
i
,
γ
i
\alpha_i, \beta_i, \gamma_i
αi,βi,γi for the query.
Restore the original
i
i
i-th query using the following steps and then answer it.
Let
B
0
=
0
B_0=0
B0=0 and
B
i
=
B_i =
Bi= (the answer to the
i
i
i-th query).
Then, the query can be decrypted as follows:
L
i
=
α
i
⊕
B
i
−
1
L_i = \alpha_i \oplus B_{i-1}
Li=αi⊕Bi−1
R
i
=
β
i
⊕
B
i
−
1
R_i = \beta_i \oplus B_{i-1}
Ri=βi⊕Bi−1
X
i
=
γ
i
⊕
B
i
−
1
X_i = \gamma_i \oplus B_{i-1}
Xi=γi⊕Bi−1
Here,
x
⊕
y
x \oplus y
x⊕y denotes the bitwise XOR of
x
x
x and
y
y
y.
All input values are integers.
1
≤
N
≤
2
×
1
0
5
1 \le N \le 2 \times 10^5
1≤N≤2×105
0
≤
A
i
≤
1
0
9
0 \le A_i \le 10^9
0≤Ai≤109
1
≤
Q
≤
2
×
1
0
5
1 \le Q \le 2 \times 10^5
1≤Q≤2×105
For the encrypted inputs, the following holds:
0
≤
α
i
,
β
i
,
γ
i
≤
1
0
18
0 \le \alpha_i, \beta_i, \gamma_i \le 10^{18}
0≤αi,βi,γi≤1018
For the decrypted queries, the following holds:
1
≤
L
i
≤
R
i
≤
N
1 \le L_i \le R_i \le N
1≤Li≤Ri≤N
0
≤
X
i
≤
1
0
9
0 \le X_i \le 10^9
0≤Xi≤109
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
Q
Q
Q
α
1
\alpha_1
α1
β
1
\beta_1
β1
γ
1
\gamma_1
γ1
α
2
\alpha_2
α2
β
2
\beta_2
β2
γ
2
\gamma_2
γ2
⋮
\vdots
⋮
α
Q
\alpha_Q
αQ
β
Q
\beta_Q
βQ
γ
Q
\gamma_Q
γQ
Output
Print
Q
Q
Q lines.
The
i
i
i-th line should contain the answer to the
i
i
i-th query.
Sample Input 1
8
2 0 2 4 0 2 0 3
5
1 8 3
10 12 11
3 3 2
3 6 5
12 0 11
Sample Output 1
9
2
0
8
5
The given sequence is
A
=
(
2
,
0
,
2
,
4
,
0
,
2
,
0
,
3
)
A=(2,0,2,4,0,2,0,3)
A=(2,0,2,4,0,2,0,3).
This input contains five queries.
Initially,
B
0
=
0
B_0=0
B0=0.
The first query is
α
=
1
,
β
=
8
,
γ
=
3
\alpha = 1, \beta = 8, \gamma = 3
α=1,β=8,γ=3.
After decryption, we get
L
i
=
α
⊕
B
0
=
1
,
R
i
=
β
⊕
B
0
=
8
,
X
i
=
γ
⊕
B
0
=
3
L_i = \alpha \oplus B_0 = 1, R_i = \beta \oplus B_0 = 8, X_i = \gamma \oplus B_0 = 3
Li=α⊕B0=1,Ri=β⊕B0=8,Xi=γ⊕B0=3.
The answer to this query is
9
9
9. This becomes
B
1
B_1
B1.
The next query is
α
=
10
,
β
=
12
,
γ
=
11
\alpha = 10, \beta = 12, \gamma = 11
α=10,β=12,γ=11.
After decryption, we get
L
i
=
α
⊕
B
1
=
3
,
R
i
=
β
⊕
B
1
=
5
,
X
i
=
γ
⊕
B
1
=
2
L_i = \alpha \oplus B_1 = 3, R_i = \beta \oplus B_1 = 5, X_i = \gamma \oplus B_1 = 2
Li=α⊕B1=3,Ri=β⊕B1=5,Xi=γ⊕B1=2.
The answer to this query is
2
2
2. This becomes
B
2
B_2
B2.
The next query is
α
=
3
,
β
=
3
,
γ
=
2
\alpha = 3, \beta = 3, \gamma = 2
α=3,β=3,γ=2.
After decryption, we get
L
i
=
α
⊕
B
2
=
1
,
R
i
=
β
⊕
B
2
=
1
,
X
i
=
γ
⊕
B
2
=
0
L_i = \alpha \oplus B_2 = 1, R_i = \beta \oplus B_2 = 1, X_i = \gamma \oplus B_2 = 0
Li=α⊕B2=1,Ri=β⊕B2=1,Xi=γ⊕B2=0.
The answer to this query is
0
0
0. This becomes
B
3
B_3
B3.
The next query is
α
=
3
,
β
=
6
,
γ
=
5
\alpha = 3, \beta = 6, \gamma = 5
α=3,β=6,γ=5.
After decryption, we get
L
i
=
α
⊕
B
3
=
3
,
R
i
=
β
⊕
B
3
=
6
,
X
i
=
γ
⊕
B
3
=
5
L_i = \alpha \oplus B_3 = 3, R_i = \beta \oplus B_3 = 6, X_i = \gamma \oplus B_3 = 5
Li=α⊕B3=3,Ri=β⊕B3=6,Xi=γ⊕B3=5.
The answer to this query is
8
8
8. This becomes
B
4
B_4
B4.
The next query is
α
=
12
,
β
=
0
,
γ
=
11
\alpha = 12, \beta = 0, \gamma = 11
α=12,β=0,γ=11.
After decryption, we get
L
i
=
α
⊕
B
4
=
4
,
R
i
=
β
⊕
B
4
=
8
,
X
i
=
γ
⊕
B
4
=
3
L_i = \alpha \oplus B_4 = 4, R_i = \beta \oplus B_4 = 8, X_i = \gamma \oplus B_4 = 3
Li=α⊕B4=4,Ri=β⊕B4=8,Xi=γ⊕B4=3.
The answer to this query is
5
5
5. This becomes
B
5
B_5
B5.
Solution
具体见文末视频。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int SIZE = 2e5 + 10;
int N;
int A[SIZE];
struct Segment
{
int l, r;
int Sum;
}Tree[SIZE * 21];
int Root[SIZE], Idx;
std::vector<int> Num;
int Build(int l, int r)
{
int P = ++ Idx;
if (l == r) return P;
int mid = l + r >> 1;
Tree[P].l = Build(l, mid), Tree[P].r = Build(mid + 1, r);
return P;
}
int Insert(int P, int l, int r, int X)
{
int Q = ++ Idx;
Tree[Q] = Tree[P];
if (l == r)
{
Tree[Q].Sum += Num[X];
return Q;
}
int mid = l + r >> 1;
if (mid >= X) Tree[Q].l = Insert(Tree[P].l, l, mid, X);
else Tree[Q].r = Insert(Tree[P].r, mid + 1, r, X);
Tree[Q].Sum = Tree[Tree[Q].l].Sum + Tree[Tree[Q].r].Sum;
return Q;
}
int Query(int P, int Q, int l, int r, int K)
{
if (l == r) return Tree[Q].Sum - Tree[P].Sum;
int S = Tree[Tree[Q].l].Sum - Tree[Tree[P].l].Sum;
int mid = l + r >> 1;
if (mid >= K) return Query(Tree[P].l, Tree[Q].l, l, mid, K);
else return S + Query(Tree[P].r, Tree[Q].r, mid + 1, r, K);
}
int Find(int X) { return lower_bound(Num.begin(), Num.end(), X) - Num.begin(); }
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], Num.push_back(A[i]);
sort(Num.begin(), Num.end());
Num.erase(unique(Num.begin(), Num.end()), Num.end());
Root[0] = Build(0, Num.size() - 1);
for (int i = 1; i <= N; i ++)
Root[i] = Insert(Root[i - 1], 0, Num.size() - 1, Find(A[i]));
int Q;
cin >> Q;
int Last = 0;
while (Q --)
{
int L, R, K;
cin >> L >> R >> K;
L ^= Last, R ^= Last, K ^= Last;
int P = upper_bound(Num.begin(), Num.end(), K) - Num.begin() - 1, Answer;
if (P >= 0)
Answer = Query(Root[L - 1], Root[R], 0, Num.size() - 1, P);
else
Answer = 0;
cout << Answer << endl;
Last = Answer;
}
return 0;
}
视频题解
Atcoder Beginner Contest 339(A ~ G 讲解)
最后祝大家早日