cp-library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub kobejean/cp-library

:heavy_check_mark: test/unittests/ds/tree/bit/bit2_cls_test.py

Depends on

Code

# verification-helper: PROBLEM https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/1/ITP1_1_A

import pytest
import random

class TestBIT2:
    def test_initialization_with_list(self):
        """Test initialization with a list of tuples"""
        values = [(1, 10), (2, 20), (3, 30), (4, 40)]
        bit = BIT2(values)
        
        assert len(bit) == 4
        assert bit[0] == (1, 10)
        assert bit[1] == (2, 20)
        assert bit[2] == (3, 30)
        assert bit[3] == (4, 40)

    def test_initialization_with_size(self):
        """Test initialization with size and zero value"""
        bit = BIT2(5, (0, 0))
        
        assert len(bit) == 5
        # All elements should be zero
        for i in range(5):
            assert bit[i] == (0, 0)

    def test_add_and_sum(self):
        """Test add and sum operations"""
        bit = BIT2(4, (0, 0))
        
        bit.add(0, (1, 10))
        bit.add(1, (2, 20))
        bit.add(2, (3, 30))
        bit.add(3, (4, 40))
        
        assert bit.sum(1) == (1, 10)
        assert bit.sum(2) == (3, 30)
        assert bit.sum(3) == (6, 60)
        assert bit.sum(4) == (10, 100)

    def test_sum_range(self):
        """Test range sum operations"""
        values = [(1, 10), (2, 20), (3, 30), (4, 40)]
        bit = BIT2(values)
        
        assert bit.sum_range(0, 2) == (3, 30)  # Sum of first two
        assert bit.sum_range(1, 3) == (5, 50)  # Sum of middle two
        assert bit.sum_range(2, 4) == (7, 70)  # Sum of last two
        assert bit.sum_range(0, 4) == (10, 100)  # Sum of all
        assert bit.sum_range(1, 1) == (0, 0)   # Empty range

    def test_set_and_get(self):
        """Test set and get operations"""
        bit = BIT2(4, (0, 0))
        
        bit[0] = (1, 10)
        bit[1] = (2, 20)
        bit[2] = (3, 30)
        bit[3] = (4, 40)
        
        assert bit[0] == (1, 10)
        assert bit[1] == (2, 20)
        assert bit[2] == (3, 30)
        assert bit[3] == (4, 40)

    def test_update_and_query(self):
        """Test update operations affect queries correctly"""
        bit = BIT2(4, (0, 0))
        
        # Initial values
        bit[0] = (1, 10)
        bit[1] = (2, 20)
        bit[2] = (3, 30)
        bit[3] = (4, 40)
        
        assert bit.sum(4) == (10, 100)
        
        # Update some values
        bit[1] = (5, 50)
        bit[2] = (6, 60)
        
        assert bit.sum(4) == (16, 160)
        assert bit.sum_range(1, 3) == (11, 110)

    def test_build_functionality(self):
        """Test that build creates correct BIT structure"""
        values = [(1, 10), (2, 20), (3, 30), (4, 40)]
        bit = BIT2(values)
        
        # Test various range sums
        assert bit.sum_range(0, 1) == (1, 10)
        assert bit.sum_range(0, 2) == (3, 30)
        assert bit.sum_range(1, 4) == (9, 90)
        
        # Test individual elements
        for i, expected in enumerate(values):
            assert bit[i] == expected

    def test_prelist(self):
        """Test prelist operation"""
        values = [(1, 10), (2, 20), (3, 30), (4, 40)]
        bit = BIT2(values)
        
        pre = bit.prelist()
        
        # Should have n+1 elements (including 0 at start)
        assert len(pre) == 5
        assert pre[0] == (0, 0)
        assert pre[1] == (1, 10)
        assert pre[2] == (3, 30)
        assert pre[3] == (6, 60)
        assert pre[4] == (10, 100)

    def test_bisect_operations(self):
        """Test bisect_left and bisect_right operations"""
        values = [(1, 10), (2, 20), (3, 30), (4, 40)]
        bit = BIT2(values)
        
        # Test bisect_right - finds rightmost position where cumsum <= v
        assert bit.bisect_right((0, 0)) == 0   # cumsum (0, 0)
        assert bit.bisect_right((1, 10)) == 1   # cumsum (1, 10)
        assert bit.bisect_right((3, 30)) == 2   # cumsum (3, 30)
        assert bit.bisect_right((6, 60)) == 3   # cumsum (6, 60)
        assert bit.bisect_right((10, 100)) == 4  # cumsum (10, 100)
        assert bit.bisect_right((15, 150)) == 4  # cumsum still (10, 100)
        
        # Test bisect_left - finds leftmost position where cumsum >= v
        assert bit.bisect_left((0, 0)) == -1
        assert bit.bisect_left((1, 10)) == 0   # sum(1)=(1,10) >= (1,10)
        assert bit.bisect_left((4, 40)) == 2   # sum(3)=(6,60) >= (4,40)  
        assert bit.bisect_left((7, 70)) == 3   # sum(4)=(10,100) >= (7,70)
        assert bit.bisect_left((11, 110)) == 4  # no cumsum >= (11,110)

    def test_empty_bit(self):
        """Test BIT with size 0"""
        bit = BIT2(0, (0, 0))
        
        assert len(bit) == 0
        assert bit.sum(0) == (0, 0)

    def test_single_element(self):
        """Test BIT with single element"""
        bit = BIT2([(5, 50)])
        
        assert len(bit) == 1
        assert bit[0] == (5, 50)
        assert bit.sum(1) == (5, 50)
        assert bit.sum_range(0, 1) == (5, 50)

    def test_large_bit(self):
        """Test with larger dataset"""
        n = 1000
        values = [(i, i * 10) for i in range(n)]
        bit = BIT2(values)
        
        # Sum of 0..999 = 499500
        assert bit.sum(n) == (499500, 4995000)
        
        # Sum of 0..99 = 4950
        assert bit.sum(100) == (4950, 49500)
        
        # Update and verify
        bit[500] = (1000, 10000)
        expected_sum = 499500 - 500 + 1000
        assert bit.sum(n) == (expected_sum, 4995000 - 5000 + 10000)

    def test_negative_values(self):
        """Test BIT with negative values"""
        values = [(-1, -10), (2, 20), (-3, -30), (4, 40)]
        bit = BIT2(values)
        
        assert bit.sum(4) == (2, 20)
        assert bit.sum_range(0, 2) == (1, 10)
        assert bit.sum_range(2, 4) == (1, 10)

    def test_zero_values(self):
        """Test BIT with zero values"""
        values = [(0, 0), (1, 10), (0, 0), (2, 20)]
        bit = BIT2(values)
        
        assert bit.sum(4) == (3, 30)
        assert bit[0] == (0, 0)
        assert bit[2] == (0, 0)

    def test_stress_random_operations(self):
        """Stress test with random operations"""
        random.seed(42)
        n = 100
        
        # Initialize with zeros
        bit = BIT2(n, (0, 0))
        naive = [(0, 0)] * n
        
        # Perform random operations
        for _ in range(200):
            op = random.choice(['add', 'set', 'query'])
            
            if op == 'add':
                idx = random.randint(0, n-1)
                val = (random.randint(-100, 100), random.randint(-100, 100))
                bit.add(idx, val)
                naive[idx] = (naive[idx][0] + val[0], naive[idx][1] + val[1])
                
            elif op == 'set':
                idx = random.randint(0, n-1)
                val = (random.randint(-100, 100), random.randint(-100, 100))
                bit[idx] = val
                naive[idx] = val
                
            else:  # query
                if random.random() < 0.5:
                    # Test sum
                    k = random.randint(1, n)
                    expected = (sum(naive[i][0] for i in range(k)), 
                               sum(naive[i][1] for i in range(k)))
                    assert bit.sum(k) == expected
                else:
                    # Test range sum
                    l = random.randint(0, n-1)
                    r = random.randint(l, n)
                    expected = (sum(naive[i][0] for i in range(l, r)), 
                               sum(naive[i][1] for i in range(l, r)))
                    assert bit.sum_range(l, r) == expected

    def test_different_types(self):
        """Test with different data types in tuples"""
        # Float values
        values = [(1.5, 10.5), (2.5, 20.5), (3.5, 30.5), (4.5, 40.5)]
        bit = BIT2(values)
        
        assert bit.sum(2) == (4.0, 31.0)
        assert bit.sum_range(1, 3) == (6.0, 51.0)

from cp_library.ds.tree.bit.bit2_cls import BIT2

if __name__ == '__main__':
    from cp_library.test.unittest_helper import run_verification_helper_unittest
    run_verification_helper_unittest()
# verification-helper: PROBLEM https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/1/ITP1_1_A

import pytest
import random

class TestBIT2:
    def test_initialization_with_list(self):
        """Test initialization with a list of tuples"""
        values = [(1, 10), (2, 20), (3, 30), (4, 40)]
        bit = BIT2(values)
        
        assert len(bit) == 4
        assert bit[0] == (1, 10)
        assert bit[1] == (2, 20)
        assert bit[2] == (3, 30)
        assert bit[3] == (4, 40)

    def test_initialization_with_size(self):
        """Test initialization with size and zero value"""
        bit = BIT2(5, (0, 0))
        
        assert len(bit) == 5
        # All elements should be zero
        for i in range(5):
            assert bit[i] == (0, 0)

    def test_add_and_sum(self):
        """Test add and sum operations"""
        bit = BIT2(4, (0, 0))
        
        bit.add(0, (1, 10))
        bit.add(1, (2, 20))
        bit.add(2, (3, 30))
        bit.add(3, (4, 40))
        
        assert bit.sum(1) == (1, 10)
        assert bit.sum(2) == (3, 30)
        assert bit.sum(3) == (6, 60)
        assert bit.sum(4) == (10, 100)

    def test_sum_range(self):
        """Test range sum operations"""
        values = [(1, 10), (2, 20), (3, 30), (4, 40)]
        bit = BIT2(values)
        
        assert bit.sum_range(0, 2) == (3, 30)  # Sum of first two
        assert bit.sum_range(1, 3) == (5, 50)  # Sum of middle two
        assert bit.sum_range(2, 4) == (7, 70)  # Sum of last two
        assert bit.sum_range(0, 4) == (10, 100)  # Sum of all
        assert bit.sum_range(1, 1) == (0, 0)   # Empty range

    def test_set_and_get(self):
        """Test set and get operations"""
        bit = BIT2(4, (0, 0))
        
        bit[0] = (1, 10)
        bit[1] = (2, 20)
        bit[2] = (3, 30)
        bit[3] = (4, 40)
        
        assert bit[0] == (1, 10)
        assert bit[1] == (2, 20)
        assert bit[2] == (3, 30)
        assert bit[3] == (4, 40)

    def test_update_and_query(self):
        """Test update operations affect queries correctly"""
        bit = BIT2(4, (0, 0))
        
        # Initial values
        bit[0] = (1, 10)
        bit[1] = (2, 20)
        bit[2] = (3, 30)
        bit[3] = (4, 40)
        
        assert bit.sum(4) == (10, 100)
        
        # Update some values
        bit[1] = (5, 50)
        bit[2] = (6, 60)
        
        assert bit.sum(4) == (16, 160)
        assert bit.sum_range(1, 3) == (11, 110)

    def test_build_functionality(self):
        """Test that build creates correct BIT structure"""
        values = [(1, 10), (2, 20), (3, 30), (4, 40)]
        bit = BIT2(values)
        
        # Test various range sums
        assert bit.sum_range(0, 1) == (1, 10)
        assert bit.sum_range(0, 2) == (3, 30)
        assert bit.sum_range(1, 4) == (9, 90)
        
        # Test individual elements
        for i, expected in enumerate(values):
            assert bit[i] == expected

    def test_prelist(self):
        """Test prelist operation"""
        values = [(1, 10), (2, 20), (3, 30), (4, 40)]
        bit = BIT2(values)
        
        pre = bit.prelist()
        
        # Should have n+1 elements (including 0 at start)
        assert len(pre) == 5
        assert pre[0] == (0, 0)
        assert pre[1] == (1, 10)
        assert pre[2] == (3, 30)
        assert pre[3] == (6, 60)
        assert pre[4] == (10, 100)

    def test_bisect_operations(self):
        """Test bisect_left and bisect_right operations"""
        values = [(1, 10), (2, 20), (3, 30), (4, 40)]
        bit = BIT2(values)
        
        # Test bisect_right - finds rightmost position where cumsum <= v
        assert bit.bisect_right((0, 0)) == 0   # cumsum (0, 0)
        assert bit.bisect_right((1, 10)) == 1   # cumsum (1, 10)
        assert bit.bisect_right((3, 30)) == 2   # cumsum (3, 30)
        assert bit.bisect_right((6, 60)) == 3   # cumsum (6, 60)
        assert bit.bisect_right((10, 100)) == 4  # cumsum (10, 100)
        assert bit.bisect_right((15, 150)) == 4  # cumsum still (10, 100)
        
        # Test bisect_left - finds leftmost position where cumsum >= v
        assert bit.bisect_left((0, 0)) == -1
        assert bit.bisect_left((1, 10)) == 0   # sum(1)=(1,10) >= (1,10)
        assert bit.bisect_left((4, 40)) == 2   # sum(3)=(6,60) >= (4,40)  
        assert bit.bisect_left((7, 70)) == 3   # sum(4)=(10,100) >= (7,70)
        assert bit.bisect_left((11, 110)) == 4  # no cumsum >= (11,110)

    def test_empty_bit(self):
        """Test BIT with size 0"""
        bit = BIT2(0, (0, 0))
        
        assert len(bit) == 0
        assert bit.sum(0) == (0, 0)

    def test_single_element(self):
        """Test BIT with single element"""
        bit = BIT2([(5, 50)])
        
        assert len(bit) == 1
        assert bit[0] == (5, 50)
        assert bit.sum(1) == (5, 50)
        assert bit.sum_range(0, 1) == (5, 50)

    def test_large_bit(self):
        """Test with larger dataset"""
        n = 1000
        values = [(i, i * 10) for i in range(n)]
        bit = BIT2(values)
        
        # Sum of 0..999 = 499500
        assert bit.sum(n) == (499500, 4995000)
        
        # Sum of 0..99 = 4950
        assert bit.sum(100) == (4950, 49500)
        
        # Update and verify
        bit[500] = (1000, 10000)
        expected_sum = 499500 - 500 + 1000
        assert bit.sum(n) == (expected_sum, 4995000 - 5000 + 10000)

    def test_negative_values(self):
        """Test BIT with negative values"""
        values = [(-1, -10), (2, 20), (-3, -30), (4, 40)]
        bit = BIT2(values)
        
        assert bit.sum(4) == (2, 20)
        assert bit.sum_range(0, 2) == (1, 10)
        assert bit.sum_range(2, 4) == (1, 10)

    def test_zero_values(self):
        """Test BIT with zero values"""
        values = [(0, 0), (1, 10), (0, 0), (2, 20)]
        bit = BIT2(values)
        
        assert bit.sum(4) == (3, 30)
        assert bit[0] == (0, 0)
        assert bit[2] == (0, 0)

    def test_stress_random_operations(self):
        """Stress test with random operations"""
        random.seed(42)
        n = 100
        
        # Initialize with zeros
        bit = BIT2(n, (0, 0))
        naive = [(0, 0)] * n
        
        # Perform random operations
        for _ in range(200):
            op = random.choice(['add', 'set', 'query'])
            
            if op == 'add':
                idx = random.randint(0, n-1)
                val = (random.randint(-100, 100), random.randint(-100, 100))
                bit.add(idx, val)
                naive[idx] = (naive[idx][0] + val[0], naive[idx][1] + val[1])
                
            elif op == 'set':
                idx = random.randint(0, n-1)
                val = (random.randint(-100, 100), random.randint(-100, 100))
                bit[idx] = val
                naive[idx] = val
                
            else:  # query
                if random.random() < 0.5:
                    # Test sum
                    k = random.randint(1, n)
                    expected = (sum(naive[i][0] for i in range(k)), 
                               sum(naive[i][1] for i in range(k)))
                    assert bit.sum(k) == expected
                else:
                    # Test range sum
                    l = random.randint(0, n-1)
                    r = random.randint(l, n)
                    expected = (sum(naive[i][0] for i in range(l, r)), 
                               sum(naive[i][1] for i in range(l, r)))
                    assert bit.sum_range(l, r) == expected

    def test_different_types(self):
        """Test with different data types in tuples"""
        # Float values
        values = [(1.5, 10.5), (2.5, 20.5), (3.5, 30.5), (4.5, 40.5)]
        bit = BIT2(values)
        
        assert bit.sum(2) == (4.0, 31.0)
        assert bit.sum_range(1, 3) == (6.0, 51.0)

'''
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
             https://kobejean.github.io/cp-library               
'''


'''
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
            ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓            
            ┃                                    7 ┃            
            ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━┛            
            ┏━━━━━━━━━━━━━━━━━━┓                 │              
            ┃                3 ┃◄────────────────┤              
            ┗━━━━━━━━━━━━━━━━┯━┛                 │              
            ┏━━━━━━━━┓       │  ┏━━━━━━━━┓       │              
            ┃      1 ┃◄──────┤  ┃      5 ┃◄──────┤              
            ┗━━━━━━┯━┛       │  ┗━━━━━━┯━┛       │              
            ┏━━━┓  │  ┏━━━┓  │  ┏━━━┓  │  ┏━━━┓  │              
            ┃ 0 ┃◄─┤  ┃ 2 ┃◄─┤  ┃ 4 ┃◄─┤  ┃ 6 ┃◄─┤              
            ┗━┯━┛  │  ┗━┯━┛  │  ┗━┯━┛  │  ┗━┯━┛  │              
              │    │    │    │    │    │    │    │              
              ▼    ▼    ▼    ▼    ▼    ▼    ▼    ▼              
            ┏━━━┓┏━━━┓┏━━━┓┏━━━┓┏━━━┓┏━━━┓┏━━━┓┏━━━┓            
            ┃ 0 ┃┃ 1 ┃┃ 2 ┃┃ 3 ┃┃ 4 ┃┃ 5 ┃┃ 6 ┃┃ 7 ┃            
            ┗━━━┛┗━━━┛┗━━━┛┗━━━┛┗━━━┛┗━━━┛┗━━━┛┗━━━┛            
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
           Data Structure - Tree - Binary Index Tree            
'''
from typing import Generic
from typing import TypeVar

_S = TypeVar('S'); _T = TypeVar('T'); _U = TypeVar('U'); _T1 = TypeVar('T1'); _T2 = TypeVar('T2'); _T3 = TypeVar('T3'); _T4 = TypeVar('T4'); _T5 = TypeVar('T5'); _T6 = TypeVar('T6')




def argsort(A: list[int], reverse=False):
    P = Packer(len(I := list(A))-1); P.ienumerate(I, reverse); I.sort(); P.iindices(I)
    return I



class Packer:
    __slots__ = 's', 'm'
    def __init__(P, mx: int): P.s = mx.bit_length(); P.m = (1 << P.s) - 1
    def enc(P, a: int, b: int): return a << P.s | b
    def dec(P, x: int) -> tuple[int, int]: return x >> P.s, x & P.m
    def enumerate(P, A, reverse=False): P.ienumerate(A:=list(A), reverse); return A
    def ienumerate(P, A, reverse=False):
        if reverse:
            for i,a in enumerate(A): A[i] = P.enc(-a, i)
        else:
            for i,a in enumerate(A): A[i] = P.enc(a, i)
    def indices(P, A: list[int]): P.iindices(A:=list(A)); return A
    def iindices(P, A):
        for i,a in enumerate(A): A[i] = P.m&a


def isort_parallel(*L: list, reverse=False):
    inv, order = [0]*len(L[0]), argsort(L[0], reverse=reverse)
    for i, j in enumerate(order): inv[j] = i
    for i, j in enumerate(order):
        for A in L: A[i], A[j] = A[j], A[i]
        order[inv[i]], inv[j] = j, inv[i]
    return L


class list2(Generic[_T1, _T2]):
    __slots__ = 'A1', 'A2'
    def __init__(lst, A1: list[_T1], A2: list[_T2]): lst.A1, lst.A2 = A1, A2
    def __len__(lst): return len(lst.A1)
    def __getitem__(lst, i: int): return lst.A1[i], lst.A2[i]
    def __setitem__(lst, i: int, v: tuple[_T1, _T2]): lst.A1[i], lst.A2[i] = v
    def __contains__(lst, v: tuple[_T1, _T2]): raise NotImplementedError
    def index(lst, v: tuple[_T1, _T2]): raise NotImplementedError
    def reverse(lst): lst.A1.reverse(); lst.A2.reverse()
    def sort(lst, reverse=False): isort_parallel(lst.A1, lst.A2, reverse=reverse)
    def pop(lst): return lst.A1.pop(), lst.A2.pop()
    def append(lst, v: tuple[_T1, _T2]): v1, v2 = v; lst.A1.append(v1); lst.A2.append(v2)
    def add(lst, i: int, v: tuple[_T1, _T2]): lst.A1[i] += v[0]; lst.A2[i] += v[1]
from typing import Generic, Union, Callable, Optional

class BITBase(Generic[_T]):
    _lst = list
    K: int = 1
    
    def __init__(bit, v: Union[int, list[_T]], e: _T = None) -> None:
        if isinstance(v, int):
            bit._n = v
            if bit._lst is list:
                bit._d = [e]*v if e is not None else [0]*v
            elif e is not None:
                bit._d = bit._lst(*([e_]*v for e_ in e))
            else:
                bit._d = bit._lst(*([0]*v for _ in range(bit.K)))
        else:
            bit.build(v)
        bit.e = e if e is not None else (0 if bit._lst is list else tuple(0 for _ in range(bit.K)))
        bit._lb = 1 << bit._n.bit_length()

    def build(bit, data: list[_T]):
        bit._n = len(data)
        if bit._lst is list:
            bit._d = bit._lst(data)
        else:
            bit._d = bit._lst(*([data[i][j] for i in range(len(data))] for j in range(len(data[0]))))
        for i in range(bit._n):
            if (r := i | i + 1) < bit._n:
                bit._add(r, bit._d[i])

    def _add(bit, i: int, x: _T) -> None:
        bit._d[i] = bit._op(bit._d[i], x)
    
    def _op(bit, a: _T, b: _T) -> _T:
        return a + b
    
    def _sub(bit, a: _T, b: _T) -> _T:
        return a - b

    def add(bit, i: int, x: _T) -> None:
        while i < bit._n: bit._add(i, x); i |= i + 1

    def sum(bit, n: int) -> _T:
        s = bit.e
        while n: s, n = bit._op(s, bit._d[n - 1]), n & n - 1
        return s

    def sum_range(bit, l: int, r: int) -> _T:
        s = bit.e
        while r: s, r = bit._op(s, bit._d[r - 1]), r & r - 1
        while l: s, l = bit._sub(s, bit._d[l - 1]), l & l - 1
        return s

    def __len__(bit) -> int: return bit._n

    def __getitem__(bit, i: int) -> _T:
        s, l = bit._d[i], i & (i + 1)
        while l != i: s, i = bit._sub(s, bit._d[i - 1]), i - (i & -i)
        return s

    get = __getitem__

    def __setitem__(bit, i: int, x: _T) -> None:
        bit.add(i, bit._sub(x, bit[i]))

    set = __setitem__

    def prelist(bit) -> list[_T]:
        pre = [bit.e] + bit._d[:] if bit._lst is list else bit._lst(*([e_] * (bit._n + 1) for e_ in bit.e))
        for i in range(bit._n): pre[i+1] = bit._d[i]
        for i in range(bit._n + 1):
            if i & i - 1 < bit._n + 1:
                pre[i] = bit._op(pre[i], pre[i & i - 1])
        return pre

    def bisect_left(bit, v, key: Optional[Callable] = None) -> int:
        i = 0
        s = bit.e
        if v <= s: return -1
        m = bit._lb
        
        if key:
            while m := m >> 1:
                if (ni := m | i) <= bit._n and key(ns := bit._op(s, bit._d[ni - 1])) < v:
                    s, i = ns, ni
        else:
            while m := m >> 1:
                if (ni := m | i) <= bit._n and (ns := bit._op(s, bit._d[ni - 1])) < v:
                    s, i = ns, ni
        return i

    def bisect_right(bit, v, key: Optional[Callable] = None) -> int:
        i = 0
        s = bit.e
        m = bit._lb
        
        if key:
            while m := m >> 1:
                if (ni := m | i) <= bit._n and key(ns := bit._op(s, bit._d[ni - 1])) <= v:
                    s, i = ns, ni
        else:
            while m := m >> 1:
                if (ni := m | i) <= bit._n and (ns := bit._op(s, bit._d[ni - 1])) <= v:
                    s, i = ns, ni
        return i

class BIT2(BITBase[tuple[int,int]]):
    _lst = list2
    K = 2
    def _add(bit, i, x) -> None: bit._d.add(i, x)
    def _op(bit, a, b): return a[0] + b[0], a[1] + b[1]
    def _sub(bit, a, b): return a[0] - b[0], a[1] - b[1]

if __name__ == '__main__':
    
    """
    Helper for making unittest files compatible with verification-helper.
    
    This module provides a helper function to run a dummy Library Checker test
    so that unittest files can be verified by oj-verify.
    """
    
    def run_verification_helper_unittest():
        """
        Run a dummy AOJ ITP1_1_A test for verification-helper compatibility.
        
        This function should be called in the __main__ block of unittest files
        that need to be compatible with verification-helper.
        
        The function:
        1. Prints "Hello World" (AOJ ITP1_1_A solution)
        2. Runs pytest for the calling test file
        3. Exits with the pytest result code
        """
        import sys
        
        # Print "Hello World" for AOJ ITP1_1_A problem
        print("Hello World")
        
        import io
        from contextlib import redirect_stdout, redirect_stderr
    
        # Capture all output during test execution
        output = io.StringIO()
        with redirect_stdout(output), redirect_stderr(output):
            # Get the calling module's file path
            frame = sys._getframe(1)
            test_file = frame.f_globals.get('__file__')
            if test_file is None:
                test_file = sys.argv[0]
            result = pytest.main([test_file])
        
        if result != 0: 
            print(output.getvalue())
        sys.exit(result)
    run_verification_helper_unittest()
Back to top page