本题除了按要求分治计算以外没有太好的手段,不过可以注意到:
(1)当n为2的幂减2时$C(n)$就是标准二分查找的得到的结果,因此可以将这种情况缓存。
(2)其它情形的关键在于每个n的第一个分支点,对分支点以下的部分可以递归计算,分支点以上的部分可以经过平移后递归计算。
(3)分支点只在2的幂附近发生改变,可以通过预处理缓存。
最终结果是$260511850222$。
f={0:(0,0),2:(1,1),6:(2,8),14:(3,31),30:(4,94),62:(5,253),126:(6,636),254:(7,1531),510:(8,3578),1022:(9,8185),2046:(10,18424),4094:(11,40951),8190:(12,90102),16382:(13,196597)}
g=(1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383)
def cal(a,b):
if b-a in f:
return f[b-a][0]*a+f[b-a][1]
i=0
while i < len(g) and g[i] < b-a:
i+=1
c=min(a+g[i-1],b-(g[i-1]-1)/2)
return c+max((cal(a,c-1),cal(c+1,b)))
c=[0,0,1,2,4,6,8]
q=[0,4,8,16,32,64,128]
i,a,n=2,3,6
while n < 200000:
n+=1
i+=(a>4**i)
s,a=min((n-a-p+max((c[n-a-p-1],cal(n-a-p+1,n))),a+p) for p in q[:i] if 0 < n-a-p < n)
c.append(s)
print sum(c)
|