結果
| 問題 | No.2581 [Cherry Anniversary 3] 28輪の桜のブーケ | 
| コンテスト | |
| ユーザー |  | 
| 提出日時 | 2024-01-07 04:13:04 | 
| 言語 | PyPy3 (7.3.15) | 
| 結果 | 
                                AC
                                 
                             | 
| 実行時間 | 919 ms / 3,000 ms | 
| コード長 | 3,091 bytes | 
| コンパイル時間 | 140 ms | 
| コンパイル使用メモリ | 82,448 KB | 
| 実行使用メモリ | 78,232 KB | 
| 最終ジャッジ日時 | 2024-09-27 19:20:39 | 
| 合計ジャッジ時間 | 14,216 ms | 
| ジャッジサーバーID (参考情報) | judge3 / judge2 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| other | AC * 32 | 
ソースコード
## https://yukicoder.me/problems/no/2581
def main():
    M = int(input())
    G = list(map(int, input().split()))
    H = list(map(int, input().split()))
    Q = int(input())
    kx = []
    for _ in range(Q):
        kx.append(list(map(int, input().split())))
    # 半分全列挙
    N = 28
    M1 = N // 2
    M2 = N - M1
    k_map = [[] for _ in range(M1 + 1)]
    for bit in range(2 ** M1):
        someyosino_count = 0
        x = 0
        for i in range(M1):
            if bit & (1 << i) > 0:
                someyosino_count += 1
                x += G[i]
            else:
                x += H[i]
        
        x %= M
        k_map[someyosino_count].append(x)
    
    for i in range(M1 + 1):
        k_map[i].sort()
    k_map2 = [[] for _ in range(M2 + 1)]
    for bit in range(2 ** M2):
        someyosino_count = 0
        x = 0
        for i in range(M2):
            if bit & (1 << i) > 0:
                someyosino_count += 1
                x += G[M1 + i]
            else:
                x += H[M1 + i]
        
        x %= M
        k_map2[someyosino_count].append(x)
    for k0, x in kx:
        count = 0
        for k2 in range(min(M2, k0) + 1):
            k1 = k0 - k2
            if k1 > M1:
                continue
            for x2 in k_map2[k2]:
                a_flg = False
                if x2 <= x:
                    # and条件
                    a_flg = True
                    lower_x1 = x - x2
                    upper_x1 = M - 1 - x2
                else:
                    # or条件
                    lower_x1 = (x - x2) % M
                    upper_x1 = M - 1 - x2
                
                # lower_x1についての2部探索
                l_x = len(k_map[k1])
                if k_map[k1][-1] >= lower_x1:
                    low = 0
                    high = len(k_map[k1]) - 1
                    while high - low > 1:
                        mid = (low + high) // 2
                        if k_map[k1][mid] >= lower_x1:
                            high = mid
                        else:
                            low = mid
                    if k_map[k1][low] >= lower_x1:
                        l_x = low
                    else:
                        l_x = high
                u_x = -1
                if k_map[k1][0] <= upper_x1:
                    low = 0
                    high = len(k_map[k1]) - 1
                    while high - low > 1:
                        mid = (low + high) // 2
                        if k_map[k1][mid] <= upper_x1:
                            low = mid
                        else:
                            high = mid
                    if k_map[k1][high] <= upper_x1:
                        u_x = high
                    else:
                        u_x = low
                if a_flg:
                    count += u_x - l_x + 1   
                else:
                    count += len(k_map[k1]) - l_x + u_x + 1  
        
        print(count)
                
                    
        
        
if __name__ == "__main__":
    main()
            
            
            
        