QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#73691#5424. NaN in a HeapdnialhTL 91ms10356kbPython32.0kb2023-01-27 16:26:372023-01-27 16:26:40

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-01-27 16:26:40]
  • 评测
  • 测评结果:TL
  • 用时:91ms
  • 内存:10356kb
  • [2023-01-27 16:26:37]
  • 提交

answer

from functools import cache

MOD = 10 ** 9 + 7

def inv(x):
    return pow(x, MOD - 2, MOD)

@cache
def solve_inv(m):
    if m <= 1:
        return 1

    h = m.bit_length()

    if m >= 3 << (h - 2):
        left = (1 << (h - 1)) - 1
        right = m - left - 1
    else:
        right = (1 << (h - 2)) - 1
        left = m - right - 1

    #print(m, h, left ,right)

    assert left == 0 or left.bit_length() == h - 1
    assert right == 0 or right.bit_length() in [h - 1, h - 2]

    rec = (solve_inv(left) * solve_inv(right)) % MOD
    return (rec * m) % MOD

@cache
def solve(m):
    return inv(solve_inv(m))

@cache
def solve_nan(m):
    if m == 0:
        return []
    elif m == 1:
        return [(0, 1)]

    h = m.bit_length()

    if m >= 3 << (h - 2):
        left = (1 << (h - 1)) - 1
        right = m - left - 1
    else:
        right = (1 << (h - 2)) - 1
        left = m - right - 1

    rec_l = solve(left)
    rec_r = solve(right)
    recn_l = solve_nan(left)
    recn_r = solve_nan(right)

    out = [(m - 1, (rec_l * rec_r % MOD) % MOD)]

    out_l = []
    for u, v in recn_l:
        rec = (v * rec_r) % MOD
        out_l.append((u, (inv(right + left - u) * rec) % MOD))
    out_r = []
    for u, v in recn_r:
        rec = (v * rec_l) % MOD
        out_r.append((u, (inv(right + left - u)  * rec) % MOD))

    while out_l or out_r:
        if len(out_l) == 0:
            out.append(out_r.pop())
        elif len(out_r) == 0 or out_l[-1][0] > out_r[-1][0]:
            out.append(out_l.pop())
        elif out_l[-1][0] < out_r[-1][0]:
            out.append(out_r.pop())
        else:
            u1, v1 = out_l.pop()
            u2, v2 = out_r.pop()

            assert u1 == u2
            out.append((u1, (v1 + v2) % MOD))

    return out[::-1]


t = int(input())
for _ in range(t):
    n = int(input())
    #n = random.randint(1, 10 ** 9)

    out = 0
    for _, v in solve_nan(n):
        out += v

    print(((out % MOD) * inv(n)) % MOD)

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 8ms
memory: 8720kb

input:

5
1
3
7
10
20221218

output:

1
666666672
55555556
596445110
3197361

result:

ok 5 number(s): "1 666666672 55555556 596445110 3197361"

Test #2:

score: 0
Accepted
time: 91ms
memory: 10356kb

input:

1000
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...

output:

1
1
666666672
375000003
633333338
97222223
55555556
822222228
123456791
596445110
229888169
878681664
673617560
436681157
699563287
68610901
902106812
308824953
904504598
779800169
693423362
328728506
466956451
68896808
88594095
156207594
533144330
758445723
92289701
206321076
267778621
266415260
48...

result:

ok 1000 numbers

Test #3:

score: -100
Time Limit Exceeded

input:

1000
1000000000
999999999
999999998
999999997
999999996
999999995
999999994
999999993
999999992
999999991
999999990
999999989
999999988
999999987
999999986
999999985
999999984
999999983
999999982
999999981
999999980
999999979
999999978
999999977
999999976
999999975
999999974
999999973
999999972
9999...

output:

191769339
839078655
63430702
488796230
588110810
163742647
964465260
961862258
425060141
344042065
747463620
143548999
281463738
797756640
382302841
365802993
511891059
902367958
70796927
495040138
33561329
728278059
879674300
992542203
309248753
251669085
188046077
672990625
635281273
113409431
972...

result: