QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#288663#6126. Sequence and SequenceCrysflyAC ✓440ms8556kbPython32.5kb2023-12-23 10:57:172023-12-23 10:57:17

Judging History

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

  • [2023-12-23 10:57:17]
  • 评测
  • 测评结果:AC
  • 用时:440ms
  • 内存:8556kb
  • [2023-12-23 10:57:17]
  • 提交

answer

from math import isqrt

# ======== 预处理:多项式 f 和 F 的点值表示 ========

# 多项式最大次数
MAX_K = 30

# prod[i][j] = product(i - k), 0 <= k <= j, k != i
prod = []
for i in range(MAX_K + 1):
    prod.append([])
    p = 1
    for j in range(MAX_K + 1):
        if i != j:
            p *= i - j
        prod[-1].append(p)

# 给 k 次多项式的点值表示 (0, y[0]), (1, y[1]), ..., (k, y[k])
# 利用拉格朗日插值法,求自变量为 x 时多项式的值
def eval(x, y):
    if x >= 0 and x < len(y):
        return y[x]

    p = 1
    for i in range(len(y)):
        p *= x - i

    nume, deno = 0, 1
    for i in range(len(y)):
        a = y[i] * (p // (x - i))
        b = prod[i][len(y) - 1]
        nume = nume * b + deno * a
        deno *= b
    return nume // deno

# 最大递归深度
MAX_DEP = 4

# polys[i] 是 f^{(i)}(x) 的点值表示
polys = []
polys.append([1])
# smPolys[i] 是 F^{(i)}(x) 的点值表示
smPolys = []

for _ in range(MAX_DEP):
    prevLen = len(polys[-1])

    # F^{(i)}(x) 是 f^{(i)}(x) 的前缀和
    sm = [0]
    for y in polys[-1][1:]:
        sm.append(sm[-1] + y)
    sm.append(sm[-1] + eval(prevLen, polys[-1]))
    smPolys.append(sm)

    # f^{(i + 1)}(x) = F^{(i)}(x * (x + 1) // 2 - 1)
    sq = []
    for x in range(0, prevLen * 2 + 1):
        sq.append(eval(x * (x + 1) // 2 - 1, sm))
    polys.append(sq)

# ======== 预处理:P 和 Q 小范围的值 ========

# 最大递归深度时,n < MAX_LEN
MAX_LEN = 610

P = [0]
t = 1
while len(P) <= MAX_LEN:
    for _ in range(t + 1):
        P.append(t)
    t += 1

Q = [0, 1]
for i in range(2, MAX_LEN):
    Q.append(Q[-1] + Q[P[i]])

# ======== 预处理:g(d, n) 在 d <= MAX_DEP,n < MAX_LEN 时的值 ========

# S[d][n] = g(d, n)
S = []
for i in range(MAX_DEP + 1):
    S.append([0])
    for j in range(1, MAX_LEN):
        S[-1].append(S[-1][-1] + eval(j, polys[i]) * Q[P[j]])

# ======== 正式计算 ========

# 若 P(n) = p,则 (p + 3) * p // 2 >= n 且 p 最小
# 通过解二次方程算出来,因为开根号和除法都下取整了,要往后检查几个数
def calcP(n):
    p = (isqrt(8 * n + 9) - 3) // 2
    while p * (p + 3) // 2 < n:
        p += 1
    return p

def g(d, n):
    if n < MAX_LEN:
        return S[d][n]
    np = calcP(n)
    return eval(n, smPolys[d]) * g(0, np) - g(d + 1, np)

T = int(input())
for _ in range(T):
    n = int(input())
    print(g(0, n))

詳細信息

Test #1:

score: 100
Accepted
time: 31ms
memory: 8556kb

input:

4
10
100
1000
987654321123456789

output:

30
2522
244274
235139898689017607381017686096176798

result:

ok 4 lines

Test #2:

score: 0
Accepted
time: 175ms
memory: 8428kb

input:

10000
613939207402503646
408978283345333197
976677512231308716
629053280913850466
148712339
236220313279945487
590396556995977994
9226
215693877607285701
649702683896705
343173887453826567
847003949499596615
867133040287550291
159928123569892354
864534948175618654
209739383170746721
4295456752378791...

output:

91030728117067063595428375419346402
40469246710473908695676971059074376
229951682342450470520349294486964970
95558039501640054006660579352994194
5418340556433412
13536357243714243974772906966693552
84197207203086091733385317631619504
20934656
11291075621624104092841708040651034
104019777231815308683...

result:

ok 10000 lines

Test #3:

score: 0
Accepted
time: 78ms
memory: 8496kb

input:

1000
6403632579734162001008235137760132245297
1307698664787972023762442022139627469666
668870338048562416595095770565441759482
5092270
8806864498496723812760785099973409980711
2178464116010775202899984038946879469187
204381824371
8638495456004772442511643693521120926431
45954412333082528168092594892...

output:

9822905445826021159291522774438593145331066315784567505849706373529921001845336
409552844852728078841401625660602682494169687360338453221088647649526339235330
107160056181509722327918304399871120167096186888511567354513496578559803370274
6354453295964
185817323129718525790559571287806776421589155460...

result:

ok 1000 lines

Test #4:

score: 0
Accepted
time: 115ms
memory: 8456kb

input:

2000
2587627816607030340103003175959756184662
7728753705064569253253827797978613582938
6507847628603052973674714721
6989857636824717968431061258300652290539
4734281027640913533293237760425416005062
9411123735455625690768098631226366597446
8309753930995253536640660321476246470149
63565157427098067709...

output:

1603610451790269237852635641930301658193367441164307312552842461667027137613454
14309943493171496191506053530749878345271155973702143153225815632926701434642842
10414697803791950572309383355053080338229465674803757518
11704102206894264239190418551798088411458157423624785417336589284698838535371266
5...

result:

ok 2000 lines

Test #5:

score: 0
Accepted
time: 235ms
memory: 8428kb

input:

5000
6701025283447923273597553918313900029215
1618190467906965189844764312914748628527
2135261797018456059451326428589353332126
8027429917075086154217136768450383650445
8263301530632040969183919589286944799002
376886964626613356031779878
1191561726595055348898524031899625958102
453561433135467095374...

output:

10756647971303093856509780939435968749671842310025383400207261624750784751725876
627115945498078452730193858129037650151913122482133071938783012929533045529940
1091921493223233296724616654299408127388059493196845968361252389122720100379070
154375707400033063668088306493199269136326791073281723548116...

result:

ok 5000 lines

Test #6:

score: 0
Accepted
time: 440ms
memory: 8496kb

input:

10000
260865660295317278841
5232352637620496342310336202478387251106
7108789244285764135987032973912918380
12766535319519586095540974948550152061
5138306300154916887884637635208203681949
7603163140266839847784708214115317398585
149590294591155205497765668766786424787
63283557694500045989299147454323...

output:

16323111740957704392106241109891718054228
6557703685144914472554701877112177422100848067214049191882271294010013621817762
12143115079716078114619105501427985631361994195400195527663921137836417758
39139456824156526604158618001888125076786817219954316014947704612553450312
6324051018379978443719363340...

result:

ok 10000 lines