Rank: 821

🔗 A - ?UPC (abc388 A)

題意

給定一個字串 SS。輸出由 SS 的第一個字元與 UPC 連接而成的字串。

思路

直接輸出即可。

1
2
S = input()
print(S[0] + "UPC")

🔗 B - Heavy Snake (abc388 B)

tags: 模擬(Simulation)

題意

NN 條蛇。一開始,第 ii 條蛇的粗細為 TiT_i,長度為 LiL_i。蛇的重量定義為其粗細 TiT_i 與長度 LiL_i 的乘積。

現在你可以增加每條蛇的長度,增加的長度為 kk,其中 kk11DD 之間的整數。對於每個滿足 1kD1 \leq k \leq D 的整數 kk,找出當每條蛇的長度都增加 kk 後,最重的蛇的重量。

約束條件

  • 1N,D1001 \leq N, D \leq 100

思路:模擬(Simulation)

注意到 DD 的範圍很小,因此可以對 kk 進行枚舉,分別計算每個 kk 時,最重的蛇的重量。

複雜度分析

  • 時間複雜度:O(D×N)O(D \times N)
  • 空間複雜度:O(N)O(N)
1
2
3
4
5
6
7
8
N, D = map(int, input().split())
snakes = [list(map(int, input().split())) for _ in range(N)]

for k in range(1, D + 1):
ans = -float('inf')
for i, (Ti, Li) in enumerate(snakes):
ans = max(ans, (Li + k) * Ti)
print(ans)

🔗 C - Various Kagamimochi (abc388 C)

tags: 雙指標(Two Pointers) 枚舉右維護左

題意

NN 個年糕,第 ii 個年糕的大小為 AiA_i,其中 (1iN)(1 \leq i \leq N),並且 AiA_i 已經按照大小以升序排列。

製作一個鏡餅(疊加的年糕)需要將兩個年糕疊放在一起,且上面年糕的大小不超過下面年糕的一半。具體來說,給定兩個年糕 AABB,其大小分別為 aabb,當且僅當 ab2a \leq \frac{b}{2} 時,可以通過將年糕 AA 放在年糕 BB 上來製作一個鏡餅。

找出在給定的 NN 個年糕中,可以製作多少種不同的鏡餅。如果至少有一個年糕不同,即使年糕的大小相同,兩個鏡餅也是不同的。

約束條件

  • 2N5×1052 \leq N \leq 5 \times 10^5
  • 1Ai109 (1iN)1 \leq A_i \leq 10^9 \ (1 \leq i \leq N)
  • AiAi+1 (1i<N)A_i \leq A_{i+1} \ (1 \leq i < N)

思路:枚舉右維護左

由於 AiA_i 已經按照大小以升序排列,且當增加 bb 的大小時,滿足條件的 aa 的數量只會增加,不會減少。

因此可以使用 雙指標(Two Pointers) 枚舉右端點,並維護能疊在右端點上的左端點數量。

複雜度分析

  • 時間複雜度:O(N)O(N)
  • 空間複雜度:O(N)O(N)
1
2
3
4
5
6
7
8
9
N = int(input())
A = list(map(int, input().split()))

ans = left = 0
for right, a in enumerate(A):
while A[left] * 2 <= a:
left += 1
ans += left
print(ans)

🔗 D - Coming of Age Celebration (abc388 D)

tags: 差分陣列(Difference Arrays) 前綴和(Prefix Sum)

題意

在某個星球上,有 NN 位外星人,且他們都是未成年人。第 ii 位外星人目前擁有 AiA_i 顆石頭,並將在正好 ii 年後成為成年人。

當某人在這個星球上成為成年人時,每位至少擁有一顆石頭的 成年人 都會贈送恰好一顆石頭作為賀禮給剛成年的外星人。

找出在 NN 年後每位外星人將擁有多少顆石頭。假設未來不會有新的外星人誕生。

約束條件

  • 1N5×1051 \leq N \leq 5 \times 10^5
  • 0Ai5×1050 \leq A_i \leq 5 \times 10^5

思路:差分陣列(Difference Arrays)

首先注意到題目中的第 ii 位外星人將在 ii 年後成年,因此成年的順序即為給定的陣列順序 1,2,,N1, 2, \cdots, N。接著,將 iijj 收到石頭視為 jj 給出石頭給 ii,其中 j<ij < i。如此便能在 ii 成年時計算其收到的石頭數量,並依此計算給出的石頭數量。

轉換後便可以從維護收到的石頭數量下手,對於第 ii 位外星人,若其能夠給出 gg 個石頭,則編號為 [i+1,i+g][i+1, i+g] 的外星人,其收到石頭數量增加 11,這種區間加操作可以用 差分陣列(Difference Arrays) 維護。

對差分陣列做前綴和即可得到 ii 從前面的人那裡收到的石頭數量 curcur。而根據原本的石頭數量 AiA_icurcur,以及後面的人數量 NiN - i,可以算出給出的石頭數量 gg,最終第 ii 位外星人的石頭數量為 Ai+curgA_i + cur - g

複雜度分析

  • 時間複雜度:O(N)O(N)
  • 空間複雜度:O(N)O(N)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
N = int(input())
A = list(map(int, input().split()))

d = [0] * (N + 1)
ans = [0] * N
cur = 0 # 收到的石頭數量,對差分陣列做前綴和得到
for i, x in enumerate(A):
cur += d[i]
give = min(x + cur, N - 1 - i) # 給出的石頭數量,這裡為 0-based
if give > 0:
# 區間 [i + 1, i + give] 的石頭數量增加 1
d[min(i + 1, N)] += 1
d[min(i + give + 1, N)] -= 1
ans[i] = x + cur - give
print(*ans)

🔗 E - Simultaneous Kagamimochi (abc388 E)

tags: 二分搜尋(Binary Search) 貪心(Greedy) 雙指標(Two Pointers) 預處理(Preprocessing)

題意

NN 個年糕,第 ii 個年糕的大小為 AiA_i,其中 (1iN)(1 \leq i \leq N),並且 AiA_i 已經按照大小以升序排列。

製作一個鏡餅(疊加的年糕)需要將兩個年糕疊放在一起,且上面年糕的大小不超過下面年糕的一半。具體來說,給定兩個年糕 AABB,其大小分別為 aabb,當且僅當 ab2a \leq \frac{b}{2} 時,可以通過將年糕 AA 放在年糕 BB 上來製作一個鏡餅。

現在你需要計算可以同時製作多少個鏡餅。

更精確地說,找出最大的非負整數 KK,使得以下條件成立:

  • NN 個年糕中選出 2K2K 個,形成 KK 對。對於每一對,將其中一個年糕疊在另一個上,製作 KK 個鏡餅。

約束條件

  • 2N5×1052 \leq N \leq 5 \times 10^5
  • 1Ai109 (1iN)1 \leq A_i \leq 10^9 \ (1 \leq i \leq N)
  • AiAi+1 (1i<N)A_i \leq A_{i+1} \ (1 \leq i \lt N)

基於貪心原則,為了盡可能組成 kk 對,則上面的 kk 個年糕應盡可能的小,也就是說,在上面的 kk 個年糕最好是最小的 kk 個。

方法一:O(NlogN)O(N \log N)

而若存在 kk 對,則最小的 kk 個年糕和區間內其他 kk 個年糕存在有效的配對,此時將某個年糕與尚未使用且更大的年糕交換,必也能配對成功。換句話說,若存在 kk 對,則區間內最小的 kk 個年糕和最大 kk 個年糕必存在有效的配對。因此,判斷是否存在 kk 對,只需要檢查這 2k2k 個年糕是否能配對成功即可,故檢查函數 check() 的時間複雜度為 O(k)O(k)

在得到檢查函數後,由於 check() 函數有越小越合法的單調性,因此可以對 kk 進行二分搜尋,由於最大的配對數量為 N2\lfloor \frac{N}{2} \rfloor,因此需要搜尋 O(logN)O(\log N) 次。

複雜度分析

  • 時間複雜度:O(NlogN)O(N \log N)。總共進行二分搜尋 O(logN)O(\log N) 次,每次檢查需要 O(k)O(k) 時間,其中 kk 為配對數量,可以視為 O(N)O(N)
  • 空間複雜度:O(N)O(N)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
N = int(input())
A = list(map(int, input().split()))

# 是否可以組成 k 對年糕
def check(k):
for i in range(k):
if A[i] * 2 > A[N - k + i]:
return False
return True

# 二分搜尋
left, right = 0, N // 2
while left <= right:
mid = (left + right) // 2
if check(mid):
left = mid + 1
else:
right = mid - 1
print(right) # 越小越合法,求最大的合法值

方法二: O(N)O(N)

這個思路可以用在 G 題,以下用 [L,R][L, R] 表示搜尋區間,本題中只需考慮 L=1,R=NL = 1, R = N 的情況。

若區間 [L,R][L, R] 內可以組成 KK 對,則最小的 KK 個數和最大的 KK 個數必能配對成功,其中最小的 KK 個數為 [L,L+K1][L, L + K - 1],最大的 KK 個數為 [RK+1,R][R - K + 1, R]

但若最小的 KK 個數中有一個數無法配對成功,則會影響到後續的數,使後續的數需要 往後遞移 ,因此其實只考慮最小的 KK 個數的右端點 L+K1L + K - 1 、以及 [L,L+K1][L, L + K - 1] 中的最大間距 max_gapmax\_gap 即可。

  • 如果 L+K1+max_gap>RL + K - 1 + max\_gap > R,則說明往後遞移之後會超過範圍,也就是說 KK 太大了,需要縮小。

根據此思路,可以使用雙指標預處理出每個位置與下一個符合條件的位置的間距,由於本題中左端點固定為 11,因此可以維護前綴最大間距即可,如此便可以在 O(1)O(1) 時間內查詢區間內的最大間距。

複雜度分析

  • 時間複雜度:O(N+logN)=O(N)O(N + \log N) = O(N)
    • 預處理每個位置與下一個符合條件的位置的間距、計算前綴最大間距都需要 O(N)O(N) 時間。
    • 二分搜尋需要 O(logN)O(\log N) 次,在預處理後,每次檢查只需要 O(1)O(1) 時間。
  • 空間複雜度:O(N)O(N)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
N = int(input())
A = list(map(int, input().split()))

# 計算下一個符合條件的位置
nxt = [0] * N
right = 0
for i in range(N):
while right < N and 2 * A[i] > A[right]:
right += 1
nxt[i] = right

# 計算每個位置與下一個符合條件的位置的間距
gaps = [nxt[i] - i for i in range(N)]
pre = [0] * N
pre[0] = gaps[0]
for i in range(1, N):
pre[i] = max(pre[i - 1], gaps[i])

# 是否可以組成 k 對年糕
def check(k):
return k - 1 + pre[k - 1] <= N - 1

# 二分搜尋
left, right = 0, N // 2
while left <= right:
mid = (left + right) // 2
if check(mid):
left = mid + 1
else:
right = mid - 1
print(right) # 越小越合法,求最大的合法值

🔗 F - Dangerous Sugoroku (abc388 F)

tags: 動態規劃(Dynamic Programming) 矩陣快速冪 狀態壓縮 位運算(Bit Manipulation)

題意

NN 個方格排成一行,從左到右標記為 1,2,,N1, 2, \ldots, N

給定 MM 對整數 (L1,R1),,(LM,RM)(L_1, R_1), \ldots, (L_M, R_M)

當且僅當存在某個 ii 使得 LijRiL_i \leq j \leq R_i 時,方格 jj 被定義為壞的

判斷是否可以通過重複執行以下操作從方格 11 移動到方格 NN

  • 假設當前所在方格為 xx。選擇一個整數 ii,滿足以下所有條件,然後移動到方格 x+ix + i
    • AiBA \leq i \leq B
    • x+iNx + i \leq N
    • 方格 x+ix + i 不是壞的。

約束條件

  • 2N10122 \leq N \leq 10^{12}
  • 0M2×1040 \leq M \leq 2 \times 10^4
  • 1AB201 \leq A \leq B \leq 20
  • 1<LiRi<N (1iM)1 < L_i \leq R_i < N \ (1 \leq i \leq M)
  • Ri<Li+1 (1iM1)R_i < L_{i+1} \ (1 \leq i \leq M - 1)

思路:矩陣快速冪優化DP

先令 fif_i 表示到達 ii 位置的方案數(沒錯,這題甚至可以求方案數,不過因為數字很大所以需要取模),則若 iigood,則 fif_i 可以從 fiA,fiA1,fiBf_{i-A}, f_{i-A-1}, \cdots f_{i-B} 轉移,即 fi=j=ABfijf_i = \displaystyle\sum_{j=A}^{B} f_{i-j}。可以將其寫成矩陣型式。以下以 A=3,B=5A = 3, B = 5 為例:

MG=[fifi1fi2fi3fi4]=[0011110000010000010000010][fi1fi2fi3fi4fi5]M_G = \begin{bmatrix} f_i \\ f_{i-1} \\ f_{i-2} \\ f_{i-3} \\ f_{i-4} \end{bmatrix} = \begin{bmatrix} 0 & 0 & 1 & 1 & 1 \\ 1 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 \\ \end{bmatrix} \begin{bmatrix} f_{i-1} \\ f_{i-2} \\ f_{i-3} \\ f_{i-4} \\ f_{i-5} \end{bmatrix}

同樣的,若 iibad,則不存在轉移來源,這也可以寫成矩陣型式。

MB=[fifi1fi2fi3fi4]=[0000010000010000010000010][fi1fi2fi3fi4fi5]M_B = \begin{bmatrix} f_i \\ f_{i-1} \\ f_{i-2} \\ f_{i-3} \\ f_{i-4} \end{bmatrix} = \begin{bmatrix} 0 & 0 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 \\ \end{bmatrix} \begin{bmatrix} f_{i-1} \\ f_{i-2} \\ f_{i-3} \\ f_{i-4} \\ f_{i-5} \end{bmatrix}

初始狀態為 f1=1f_1 = 1,定義 f0=f1==fB+2=0f_0 = f_{-1} = \cdots = f_{-B+2} = 0,如此便可以把初始狀態寫成一個 (B×1)(B \times 1) 的矩陣。

x=[f1f0f1f2f3]=[10000]\mathbf{x} = \begin{bmatrix} f_1 \\ f_0 \\ f_{-1} \\ f_{-2} \\ f_{-3} \end{bmatrix} = \begin{bmatrix} 1 \\ 0 \\ 0 \\ 0 \\ 0 \end{bmatrix}

每次從 stst 走到 eded 時,會需要轉移 edsted - st 次,若 (st+1,ed](st + 1, ed] 性質相同,則等同於計算 Miedst{M_i}^{ed - st},注意這裡是左開右閉的區間。而題目中是若干段 goodbad 的組合,因此從 (1,L11](1, L_1 - 1]good,從 (L11,R1](L_1 - 1, R_1]bad,依此類推,不要忘了考慮最後一段 (RM,N](R_M, N]

利用 矩陣快速冪 的原理,可以把 Mik{M_i}^k 表示成 Mi2j{M_i}^{2^j} 的乘積,由於 MiM_i 是大小為 B×BB \times B 的矩陣,因此計算 Mik{M_i}^k 等同計算若干個 (B×B)(B \times B) 的矩陣相乘。

但直接上矩陣快速冪會超時,這是因為每次我們會重複計算 Mi2jM_i^{2^j} 的矩陣,且計算兩個 (B×B)(B \times B) 的矩陣相乘需要 O(B3)O(B^3) 的時間,因此總共需要 O(M×B3logU)O(M \times B^3 \log U) 的時間,根據本題的資料範圍,約等於 2×104×203log10126.4×1092 \times 10^4 \times 20^3 \log 10^{12} \approx 6.4 \times 10^9,是會超時的。

為此,需要考慮一些手段來加速:

  1. 預先處理 Mi2j{M_i}^{2^j} 的矩陣。
    • 可以注意到,在轉移時我們只存在兩種矩陣 MGM_GMBM_B,因此可以預先處理出 MG2jM_G^{2^j}MB2jM_B^{2^j} 的矩陣,預處理需要 O(B3)×logUO(B^3) \times \log U 的時間。
  2. 由後往前計算,這樣可以減少計算的次數。
    • 由於初始狀態為一個 (B×1)(B \times 1) 的矩陣,因此我們實際上是計算 O(M×logU)O(M \times \log U)(B×B)(B \times B) 的矩陣相乘後再乘以一個 (B×1)(B \times 1) 的矩陣。
    • 但兩個 (B×B)(B \times B) 的矩陣相乘需要 O(B3)O(B^3) 的時間;而 (B×B)(B \times B) 的矩陣乘以 (B×1)(B \times 1) 的矩陣只需要 O(B2)O(B^2) 的時間。
    • 因此我們應該由後往前計算,這樣可以減少計算的次數,如此便可以在 O(B2logk)O(B^2 log k) 的時間內計算出 MBk×x{M_B}^k \times \mathbf{x}

由於本題是求可行性,但如果使用求方案數取模的話,可能會有取模後為 00 的情況,因此可以修改原本的加法為或運算,原本的乘法為與運算。最後判斷 fNf_N 是否為 11 即可。

也可以利用求可行性的性質,將矩陣狀態壓縮M×1M \times 1 的矩陣,並直接利用位運算加速,如此便可以把兩個 (B×B)(B \times B) 的矩陣相乘的時間壓縮到 O(B2)O(B^2),但注意 B×BB \times BB×1B \times 1 的矩陣相乘仍然需要 O(B2)O(B^2) 的時間。由於上述加速就已經足夠了,因此這裡不對此方法做詳述。

複雜度分析

  • 時間複雜度:O(B3logU+M×B2logU)O(B^3 \log U + M \times B^2 \log U)
    • 預處理 MG2jM_G^{2^j}MB2jM_B^{2^j} 需要 O(B3logU)O(B^3 \log U) 的時間。
    • 總共有 O(M)O(M) 個區間,對每個區間做轉移需要 O(B2logU)O(B^2 \log U) 的時間。
  • 空間複雜度:O(M+B2logU)O(M + B^2 \log U)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
N, M, A, B = map(int, input().split())
intervals = [tuple(map(int, input().split())) for _ in range(M)]

class Matrix:
def __init__(self, mat):
self.mat = mat

def __mul__(self, other):
p, q, r = len(self.mat), len(other.mat), len(other.mat[0])
res = [[0] * r for _ in range(p)]
for k in range(q):
for i in range(p):
for j in range(r):
res[i][j] |= self.mat[i][k] & other.mat[k][j]
return Matrix(res)

def __getitem__(self, key):
i, j = key
return self.mat[i][j]

def __setitem__(self, key, value):
i, j = key
self.mat[i][j] = value

MG = Matrix([[0] * B for _ in range(B)]) # Good
for i in range(A - 1, B):
MG[0, i] = 1
for i in range(1, B):
MG[i, i - 1] = 1

MB = Matrix([[0] * B for _ in range(B)]) # Bad
for i in range(1, B):
MB[i, i - 1] = 1

pow_MG, pow_MB = [0] * 41, [0] * 41
pow_MG[0], pow_MB[0] = MG, MB
for i in range(1, 41):
pow_MG[i] = pow_MG[i - 1] * pow_MG[i - 1]
pow_MB[i] = pow_MB[i - 1] * pow_MB[i - 1]

def pow(x, k, pow_mat):
res = x
for i in range(41):
if k & (1 << i):
res = pow_mat[i] * res
return res

cur = 1
m = [[0] for _ in range(B)]
m[0] = [1]
x = Matrix(m)
for (L, R) in intervals:
# (cur, L-1] is good
x = pow(x, L - 1 - cur, pow_MG)
# (L-1, R] is bad
x = pow(x, R - L + 1, pow_MB)
cur = R

# (cur, N] is good
x = pow(x, N - cur, pow_MG)
print("Yes" if x[0, 0] else "No")

🔗 G - Simultaneous Kagamimochi 2 (abc388 G)

tags: 貪心(Greedy) 二分搜尋(Binary Search) 線段樹(Segment Tree)

題意

NN 個年糕,第 ii 個年糕的大小為 AiA_i,其中 (1iN)(1 \leq i \leq N),並且 AiA_i 已經按照大小以升序排列。

製作一個鏡餅(疊加的年糕)需要將兩個年糕疊放在一起,且上面年糕的大小不超過下面年糕的一半。具體來說,給定兩個年糕 AABB,其大小分別為 aabb,當且僅當 ab2a \leq \frac{b}{2} 時,可以通過將年糕 AA 放在年糕 BB 上來製作一個鏡餅。

現在給定 QQ 區間,令 (Li,Ri)(L_i , R_i) 為第 ii 個區間 (1iQ)(1\leq i\leq Q),並為每個 ii 解決以下問題:

  • 僅使用從第 [Li,Ri][L_i, R_i] 之間的 RiLi+1R_i - L_i + 1 個麻糬,最多可以同時製作多少個鏡餅?
  • 更精確地說,找出最大的非負整數 KK,使得以下條件成立:
    • 從第 [Li,Ri][L_i, R_i] 之間的 RiLi+1R_i - L_i + 1 個麻糬中,選出 2K2K 個麻糬並形成 KK 對。對於每一對,將一個麻糬放在另一個上面,製作 KK 個鏡餅。

約束條件

  • 2N2×1052 \leq N \leq 2 \times 10^5
  • 1Ai109 (1iN)1 \leq A_i \leq 10^9 \ (1 \leq i \leq N)
  • AiAi+1 (1i<N)A_i \leq A_{i+1} \ (1 \leq i < N)
  • 1Q2×1051 \leq Q \leq 2 \times 10^5
  • 1Li<RiN (1iQ)1 \leq L_i < R_i \leq N \ (1 \leq i \leq Q)

思路:貪心 + 二分搜尋 + 線段樹/稀疏表

本題和 EE 題類似,都需要求區間內的最大配對數,但如果使用 O(k)O(k) 的檢查函數做二分搜尋會超時,因此需要和方法二一樣預處理後,利用該性質進行二分搜尋。

若區間 [L,R][L, R] 內可以組成 KK 對,則最小的 KK 個數和最大的 KK 個數必能配對成功,其中最小的 KK 個數為 [L,L+K1][L, L + K - 1],最大的 KK 個數為 [RK+1,R][R - K + 1, R]

但若最小的 KK 個數中有一個數無法配對成功,則會影響到後續的數,使後續的數需要 往後遞移 ,因此其實只考慮最小的 KK 個數的右端點 L+K1L + K - 1 、以及 [L,L+K1][L, L + K - 1] 中的最大間距 max_gapmax\_gap 即可。

  • 如果 L+K1+max_gap>RL + K - 1 + max\_gap > R,則說明往後遞移之後會超過範圍,也就是說 KK 太大了,需要縮小。

根據此思路,可以預先計算出每個位置與下一個符合條件的位置的間距,並使用 線段樹(Segment Tree)稀疏表(Sparse Table) 維護區間內的最大間距,如此便可以在 O(logN)O(\log N) 時間內查詢區間 [L,L+K1][L, L + K - 1] 內的最大間距,檢查函數為 L+K1+max_gapRL + K - 1 + max\_gap \leq R

如果對線段樹不夠熟練,或是使用的線段樹模板不夠好的話,可能會超時,因此這裡直接使用 Atcoder Library 的線段樹模板。

複雜度分析

  • 時間複雜度:O(N+Q(logN)2)O(N + Q \cdot (\log N)^2)
    • 預處理每個位置與下一個符合條件的位置的間距,並以此建立線段樹需要 O(N)O(N) 時間。
    • 二分搜尋需要 O(logN)O(\log N) 次,在預處理後,每次檢查只需要查詢線段樹,時間為 O(logN)O(\log N),故對於每個詢問,時間複雜度為 O((logN)2)O((\log N)^2)
  • 空間複雜度:O(N)O(N)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from atcoder.segtree import SegTree

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

# 計算下一個符合條件的位置
nxt = [0] * N
right = 0
for i in range(N):
while right < N and 2 * A[i] > A[right]:
right += 1
nxt[i] = right

# 計算每個位置與下一個符合條件的位置的間距
gaps = [nxt[i] - i for i in range(N)]
seg = SegTree(lambda x, y: max(x, y), -float('inf'), gaps) # 維護區間內的最大間距

Q = int(input())
queries = [list(map(int, input().split())) for _ in range(Q)]
for (L, R) in queries:

def check(k):
# 查詢 [L, L+mid) 區間內的最大間距
max_gap = seg.prod(L - 1, L - 1 + mid) # 0-based
return L + k - 1 + max_gap <= R

left, right = 0, (R - L + 1) // 2
while left <= right:
mid = (left + right) // 2
if check(mid):
left = mid + 1
else:
right = mid - 1
print(right) # 越小越合法,求最大的合法值

寫在最後

PROMPT

Kamisato Ayaka, Kamisato Ayaka (Genshin Impact), kamisato ayaka,

1girl, solo, long hair, looking at viewer, blush, smile, bangs, blue eyes, skirt, shirt, hair ornament, long sleeves, bow, ribbon, closed mouth, blue hair, standing, jacket, hair ribbon, white shirt, ponytail, flower, white hair, sidelocks, outdoors, open clothes, sky, alternate costume, hair flower, blunt bangs, mole, open jacket, tree, plaid, petals, mole under eye, night, feet out of frame, plaid skirt, white jacket, cherry blossoms, building, night sky, pink flower, puffy long sleeves, lantern, railing, architecture, east asian architecture, falling petals,

Anime style, female character in traditional Japanese outfit, standing on a wooden balcony, surrounded by cherry blossoms, night sky with stars, traditional Japanese buildings, romantic and serene atmosphere.

賽時只有寫了 AAEE 題,看到通過人數決定先去寫 GG 題,但沒想出來就直接去休息了。賽後看完 FF 題才發現這道題我是有可能寫出來的題目,賽時不應該沒看就直接放棄的。