結果
| 問題 |
No.911 ラッキーソート
|
| コンテスト | |
| ユーザー |
lam6er
|
| 提出日時 | 2025-04-09 20:57:29 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 158 ms / 2,000 ms |
| コード長 | 4,260 bytes |
| コンパイル時間 | 364 ms |
| コンパイル使用メモリ | 82,112 KB |
| 実行使用メモリ | 113,004 KB |
| 最終ジャッジ日時 | 2025-04-09 20:59:15 |
| 合計ジャッジ時間 | 7,235 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 46 |
ソースコード
def main():
import sys
N, L, R = map(int, sys.stdin.readline().split())
A = list(map(int, sys.stdin.readline().split()))
if N == 1:
print(max(0, R - L + 1))
return
# Process each adjacent pair
from collections import defaultdict
mask_dict = defaultdict(lambda: None)
conflict = False
for i in range(N-1):
a = A[i]
b = A[i+1]
if a < b:
original_order = 'asc'
else:
original_order = 'desc'
y = a ^ b
if y == 0:
continue # impossible given problem constraints
k = y.bit_length() - 1 # MSB position (0-based)
# Determine required bit value for x at k-th position
a_bit = (a >> k) & 1
b_bit = (b >> k) & 1
if original_order == 'asc':
required_bit = 0
else:
required_bit = 1
# Check for conflicts
if mask_dict[k] is not None and mask_dict[k] != required_bit:
conflict = True
break
mask_dict[k] = required_bit
if conflict:
print(0)
return
# Construct fixed_mask and fixed_value
fixed_mask = 0
fixed_value = 0
for bit in mask_dict:
req = mask_dict[bit]
fixed_mask |= (1 << bit)
fixed_value |= (req << bit)
# Now, compute the count of x in [L, R] where x & fixed_mask == fixed_value
def count_masked(L, R, mask, value):
if mask == 0:
if value != 0:
return 0
return max(0, R - L + 1)
free_mask = (~mask) & ((1 << 61) - 1)
# x must be value | s where s is a subset of free_mask's bits
# Use digit DP to count s where (value ^ s) is between L and R
# And s is a subset of free_mask
# DP state: [pos][loose_low][loose_high]
dp_prev = [[0]*2 for _ in range(2)]
dp_prev[0][0] = 1 # start with tight lower and upper
for pos in reversed(range(61)): # process from 60 downto 0
current_bit = pos
dp_curr = [[0]*2 for _ in range(2)]
for loose_low in [0, 1]:
for loose_high in [0, 1]:
count = dp_prev[loose_low][loose_high]
if count == 0:
continue
# Determine allowed y_bit for current position
if (free_mask >> current_bit) & 1:
possible_y_bits = [0, 1]
else:
possible_y_bits = [0]
for y_bit in possible_y_bits:
x_bit = ((value >> current_bit) ^ y_bit) & 1
new_loose_low = loose_low
new_loose_high = loose_high
# Check against lower bound L
if not loose_low:
lb = (L >> current_bit) & 1
if x_bit < lb:
continue # x is less than L, invalid
elif x_bit > lb:
new_loose_low = 1 # now x is definitely >= L
# Check against upper bound R
if not loose_high:
ub = (R >> current_bit) & 1
if x_bit > ub:
continue # x is larger than R, invalid
elif x_bit < ub:
new_loose_high = 1 # now x is definitely <= R
dp_curr[new_loose_low][new_loose_high] += count
dp_prev = dp_curr
total = 0
for loose_low in [0, 1]:
for loose_high in [0, 1]:
# If after all bits processed, check if x is within [L, R]
# All transitions have ensured that x >= L and x <= R
total += dp_prev[loose_low][loose_high]
return total
result = count_masked(L, R, fixed_mask, fixed_value)
print(result)
if __name__ == '__main__':
main()
lam6er