é”Œē›®ēš„é›£åŗ¦é”č‰²ä½æē”Ø Luogu äøŠēš„åˆ†ē“šļ¼Œē”±ē°”å–®åˆ°å›°é›£åˆ†åˆ„ē‚ŗ šŸ”“šŸŸ šŸŸ”šŸŸ¢šŸ”µšŸŸ£āš«ć€‚

šŸ”— CF2178E Flatten or Concatenate

rating: 1969

Problem Statement

é”Œē›®ē°”čæ°

é€™ę˜Æäø€å€‹äŗ’å‹•é”Œć€‚
Dilhan ęœ‰å…©å€‹åˆå§‹ē‚ŗ [2k][2^k] ēš„é™£åˆ— aa 和 bbć€‚ä»–åÆä»„ä»»ę„ę¬”ę•øåŸ·č”Œä»„äø‹ę“ä½œļ¼š

  1. Flattenļ¼šéøå®šäø€å€‹é™£åˆ—äø­ēš„ęœ€å¤§å¶ę•øå…ƒē“  xxļ¼Œå°‡å…¶ę›æę›ē‚ŗå…©å€‹ x/2x/2怂
  2. Concatenateļ¼šå°‡ aa 和 bb éƒ½ę›“ę–°ē‚ŗ a+ba+bļ¼ˆé™£åˆ—äø²ęŽ„ļ¼‰ć€‚

ęœ€ēµ‚ bb č¢«äøŸę£„ļ¼Œaa č¢«éš±č—ļ¼Œé•·åŗ¦ē‚ŗ nnć€‚ä½ åÆä»„é€²č”Œęœ€å¤š 300300 ę¬”č©¢å•ļ¼ŒęÆę¬”č©¢å•å€é–“ [l,r][l, r] ēš„å’Œć€‚
ē›®ęØ™ę˜Æę±‚å‡ŗéš±č—é™£åˆ— aa äø­ēš„ęœ€å¤§å€¼ć€‚

Constraints

ē“„ęŸę¢ä»¶

  • nn (1≤n≤1051 \le n \le 10^5)怂
  • éš±č—é™£åˆ—äø­ēš„å…ƒē“  1≤ai≤2301 \le a_i \le 2^{30}怂
  • č©¢å•ę¬”ę•øé™åˆ¶ļ¼š300300怂

ę€č·Æļ¼šäŗŒåˆ†ęœå°‹

ę øåæƒč§€åÆŸ

ę“ä½œå°ēø½å’Œēš„å½±éŸæ

  • Flatten ę“ä½œļ¼šå°‡ xx ę›æę›ē‚ŗ x2,x2\dfrac{x}{2}, \dfrac{x}{2}ļ¼Œēø½å’Œäøč®Šć€‚
  • Concatenate ę“ä½œļ¼šå°‡ a,ba, b éƒ½č®Šē‚ŗ a+ba + bļ¼Œēø½å’Œēæ»å€ć€‚

å› ę­¤ļ¼Œęœ€ēµ‚é™£åˆ—ēš„ēø½å’Œäø€å®šę˜Æ 2k2^k怂

åˆ†å‰²é»žēš„ę„ē¾©

ęˆ‘å€‘åÆä»„é€éŽäŗŒåˆ†ęœå°‹ę‰¾åˆ°å‰ē¶“å’Œē­‰ę–¼ 2kāˆ’12^{k-1} ēš„ä½ē½® xxć€‚é€™å€‹åˆ†å‰²é»žåÆčƒ½ęœ‰å…©ēØ®å«ē¾©ļ¼š

  1. 來自 Concatenate ę“ä½œļ¼š

    • é™£åˆ—ę˜Æē”± [1,x][1, x] 和 [x+1,n][x+1, n] å…©å€‹å­é™£åˆ—ę‹¼ęŽ„č€Œęˆć€‚
    • ē”±ę–¼č¼ƒēŸ­ēš„å€é–“ä½æē”Ø Flatten ę“ä½œēš„ę¬”ę•øę›“å°‘ļ¼ˆå› ē‚ŗ Flatten åŖå¢žåŠ é•·åŗ¦ć€äøęø›å°‘ļ¼‰ļ¼Œę‰€ä»„ęœ€å¤§å€¼åæ…å®šč½åœØč¼ƒēŸ­ēš„å€é–“ć€‚
  2. 來自 Flatten ę“ä½œļ¼š

    • é€™å€‹å€é–“ę˜Æē”±ęŸå€‹é™£åˆ—ē¶“éŽ Flatten ę“ä½œåˆ†č£‚č€Œęˆć€‚
    • åŒęØ£åœ°ļ¼Œč¼ƒēŸ­ēš„å€é–“ä½æē”Ø Flatten ēš„ę¬”ę•øę›“å°‘ļ¼Œęœ€å¤§å€¼ä¹Ÿč½åœØč¼ƒēŸ­å€é–“ć€‚
é—œéµēµč«–

ē„”č«–ę˜Æå“ŖēØ®ęƒ…ę³ļ¼Œęœ€å¤§å€¼äø€å®šä½ę–¼é•·åŗ¦č¼ƒēŸ­ēš„é‚£äø€åŠå€é–“äø­ć€‚

äŗŒåˆ†ęœå°‹ē­–ē•„

åŸŗę–¼äøŠčæ°č§€åÆŸļ¼Œęˆ‘å€‘åÆä»„ęŽ”ē”Øä»„äø‹ē­–ē•„ļ¼š

  1. ęŸ„č©¢ęˆ–å¾žå‰äø€č¼Ŗēš„ēø½å’Œ 2S2Sļ¼Œå¾—åˆ°ē•¶å‰å€é–“ [l,r][l, r] ēš„ēø½å’Œ SS怂
  2. åˆ©ē”ØäŗŒåˆ†ęœå°‹ę‰¾åˆ°åˆ†å‰²é»ž mmļ¼Œä½æå¾— [l,m][l, m] ēš„å’Œē‚ŗ S2\dfrac{S}{2}怂
  3. ęÆ”č¼ƒå·¦å³å…©éƒØåˆ†ēš„é•·åŗ¦ļ¼Œéøę“‡č¼ƒēŸ­ēš„å€é–“ē¹¼ēŗŒč™•ē†ć€‚
  4. ē•¶å€é–“é•·åŗ¦ē‚ŗ 11 ę™‚ļ¼Œē•¶å‰ēš„ēø½å’Œ SS å³ē‚ŗč©²å…ƒē“ ēš„å€¼ļ¼Œä¹Ÿę˜Æęœ€å¤§å€¼ć€‚

ē¶“éŽäø€č¼ŖäŗŒåˆ†å¾Œļ¼Œęœ€å¤§å€¼ę‰€åœØēš„å€é–“é•·åŗ¦č‡³å°‘ēø®å°äø€åŠć€‚å› ę­¤ęœ€å¤šē¶“éŽ O(log⁔n)O(\log n) č¼ŖäŗŒåˆ†ļ¼Œå°±åÆä»„å°‡å€é–“ēø®å°č‡³ 11怂

č¤‡é›œåŗ¦åˆ†ęž

  • ę™‚é–“č¤‡é›œåŗ¦ļ¼šO(log⁔2n)\mathcal{O}(\log^2 n)
    • ęÆč¼Ŗéœ€č¦ O(log⁔n)O(\log n) ę¬”č©¢å•ä¾†äŗŒåˆ†ę‰¾åˆ†å‰²é»žļ¼Œå…± O(log⁔n)O(\log n) 輪,總計 O(log⁔2n)≤300O(\log^2 n) \le 300怂
  • ē©ŗé–“č¤‡é›œåŗ¦ļ¼šO(1)\mathcal{O}(1)

Code

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
def query(l, r):
print(f"? {l} {r}", flush=True)
return int(input())

def answer(x):
print(f"! {x}", flush=True)

def solve():
n = int(input())

l, r = 1, n
s = query(1, n)
while l < r:
# ę‰¾åˆ°åˆ†å‰²é»ž x 使得 [l, x] ēš„å€é–“å’Œ == [x + 1, r] ēš„å€é–“å’Œ
s //= 2
left, right = l, r - 1
while left <= right:
mid = (left + right) // 2
if query(l, mid) < s:
left = mid + 1
else:
right = mid - 1
# ꭤꙂ [1, left] ēš„å€é–“å’Œ == [left + 1, r] ēš„å€é–“å’Œ
# ę ¹ę“šå…©å€‹å€é–“ēš„é•·åŗ¦åˆ¤ę–·ęœ€å¤§å€¼ēš„ä½ē½®
if (left - l + 1) <= (r - left):
r = left
else:
l = left + 1
answer(s)

if __name__ == "__main__":
t = int(input())
for _ in range(t):
solve()

åÆ«åœØęœ€å¾Œ

äŗ’å‹•é”Œēš„ęœ¬åœ°ęø¬č©¦ęŠ€å·§

å°ę–¼é€™é”žäŗ’å‹•é”Œļ¼Œęˆ‘å€‘åÆä»„åœØęœ¬åœ°ę’°åÆ«äø€å€‹ Judge é”žåˆ„ä¾†ęØ”ę“¬č©•ęø¬ē³»ēµ±ēš„č”Œē‚ŗć€‚ęˆ‘å€‘åÆä»„ć€ŒåŠ«ęŒć€åŽŸęœ¬ē”Øę–¼čˆ‡č©•ęø¬ę©Ÿé€ščØŠēš„ query() 和 answer() å‡½ę•øļ¼Œå°‡å®ƒå€‘é‡ę–°ęŒ‡å‘ęœ¬åœ° Judge ēš„å°ę‡‰ę–¹ę³•ć€‚é€™ęØ£äø€ä¾†ļ¼Œęˆ‘å€‘ēš„ēØ‹å¼ē¢¼åÆä»„åœØåÆ¦éš›ęäŗ¤åˆ°č©•ęø¬ē³»ēµ±ä¹‹å‰ļ¼Œå…ˆåœØęœ¬åœ°é€²č”Œäø€å®šēš„ęø¬č©¦å’Œé©—č­‰ć€‚

Code with Judge

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
from random import randint, choice
from itertools import accumulate

DEBUG = False

class Judge:
def __init__(self, n: int):
self.n = n
self.query_count = 0
self.max_queries = 300
self.array = self._generate_array(n)
self.s = list(accumulate(self.array, initial=0))
# print(f"[DEBUG] Generated array: {self.array}")

def _generate_array(self, n: int):
k = randint(1, 30)
A, B = [1 << k], [1 << k]

def flatten(arr):
max_val = max(arr)
idx = choice([i for i, x in enumerate(arr) if x == max_val])
return arr[:idx] + [max_val // 2, max_val // 2] + arr[idx+1:]

while len(A) < n:
ops = []
if max(A) > 1:
ops.append('flatten_a')
if max(B) > 1 and len(A) + len(B) + 1 <= n:
ops.append('flatten_b')
if len(A) + len(B) <= n:
ops.append('concat')
if not ops:
k = randint(1, 30)
A, B = [1 << k], [1 << k]
continue
op = choice(ops)
if op == 'concat':
new = A + B
A = new[:]
B = new[:]
elif op == 'flatten_a':
A = flatten(A)
else:
B = flatten(B)
assert len(A) == n
return A

def query(self, l: int, r: int) -> int:
assert 1 <= l <= r <= self.n
self.query_count += 1
assert self.query_count <= self.max_queries
return self.s[r] - self.s[l - 1]

def answer(self, x: int):
print(f"[DEBUG] Answer: ! {x}")
print(f"[DEBUG] Total queries used: {self.query_count}")

if x == (ans := max(self.array)):
print("[RESULT] Correct!")
else:
print(f"[DEBUG] Generated array: {self.array}")
raise ValueError(f"Wrong answer: {x}, Correct answer: {ans}")

def query(l, r):
print(f"? {l} {r}", flush=True)
return int(input())

def answer(x):
print(f"! {x}", flush=True)

def solve():
n = int(input()) if not DEBUG else randint(1, 1500)

if DEBUG:
global query, answer
judge = Judge(n)
query = judge.query
answer = judge.answer

l, r = 1, n
s = query(1, n)
while l < r:
# ę‰¾åˆ°åˆ†å‰²é»ž x 使得 [l, x] ēš„å€é–“å’Œ == [x + 1, r] ēš„å€é–“å’Œ
s //= 2
left, right = l, r - 1
while left <= right:
mid = (left + right) // 2
if query(l, mid) < s:
left = mid + 1
else:
right = mid - 1
# ꭤꙂ [1, left] ēš„å€é–“å’Œ == [left + 1, r] ēš„å€é–“å’Œ
# ę ¹ę“šå…©å€‹å€é–“ēš„é•·åŗ¦åˆ¤ę–·ęœ€å¤§å€¼ēš„ä½ē½®
if (left - l + 1) <= (r - left):
r = left
else:
l = left + 1
answer(s)

if __name__ == "__main__":
t = int(input()) if not DEBUG else 10
for _ in range(t):
solve()