专栏文章
题解:P9885 [ICPC2018 Qingdao R] Sequence and Sequence
P9885题解参与者 2已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @miqo2re9
- 此快照首次捕获于
- 2025/12/04 07:57 3 个月前
- 此快照最后确认于
- 2025/12/04 07:57 3 个月前
模拟赛搬了这个题,写一发题解纪念我成功补掉依托shi。
以下 。
首先根据递推式我们可得:
当 时 ,所以我们希望凑出一些式子含有 的形式或 之类的形式。
接下来是一种叫“分部求和法”的神秘技巧:
令 ,,,那么:
出现了 的形式,这样我们枚举 的 ,且我们可以发现 。
于是我们枚举 :
这时我们设 ,那么我们就可以知道:
每次递归都可以把 的大小开根号。
用 估计递归四层以后 只有 的大小,可以直接预处理。
关于维护 的部分,可以维护一些连续点值,然后求值的时候直接拉插即可。
预处理时间复杂度很小,查询复杂度是 ,其中 。
python 代码:
f = [None]*5
F = [None]*5
f[0] = [1]
fc = [1]*80
for i in range(1,80):
fc[i] = fc[i-1]*i
def getf(f:list, x:int):
n = len(f)
if x < n and x>=0:
return f[x]
if n>=80:
print(n)
r = 0
m = 1
for i in range(n):
m = m*(x-i)
for i in range(n):
t = m//(x-i)*f[i]*(-1 if (n-i-1)%2==1 else 1)
r += t*(fc[n]//fc[i])*(fc[n]//fc[n-i-1])
return r//(fc[n]*fc[n])
def work2(f):
r = f.copy()
n = len(f)
r.append(getf(f,n))
r[0] = 0
for i in range(1,len(r)):
r[i] += r[i-1]
return r
def work1(f):
r = [None]*len(f)*2
for i in range(len(r)):
r[i] = getf(f,i*(i+1)//2-1)
return r
ans = [None]*5
B = 700
q = [None]*B
p = [None]*B
def init():
q[0] = 0
q[1] = 1
q[2] = 2
p[0] = 0
p[1] = p[2] = 1
idc = 2
c = 0
for i in range(3,B):
q[i] = q[i-1] + q[idc]
p[i] = idc
c += 1
if c == idc + 1:
idc += 1
c = 0
for i in range(5):
if i:
f[i] = work1(F[i-1])
F[i] = work2(f[i])
ans[i] = [None]*B
ans[i][0] = 0
for j in range(1,B):
ans[i][j] = ans[i][j-1] + getf(f[i],j)*q[p[j]]
def getp(n: int):
l = 1
r = n
while r-l>1:
mid = (l+r)>>1
if mid*(mid+3)<2*n:
l = mid
else:
r = mid
return r
def g(d:int, n:int):
if n<B:
return ans[d][n]
p = getp(n)
return getf(F[d],n)*g(0,p)-g(d+1,p)
init()
t=int(input())
for tc in range(t):
n=int(input())
print(g(0,n))
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...