2023牛客暑期多校训练营10 C Multiplication(复杂度证明)

拿了个一血,队友说复杂度可能有问题,我就来证一证
做法就不说了,题解里有,贴个代码

def gcd(a,b):
    if (b==0):return a
    return gcd(b,a%b)
n=int(input())
k=int(input())
ans=0
for x in range(0,102):
    for y in range(0,102-x):
        xx=10**x
        yy=10**y
        a=yy-k
        b=k*xx-1
        if (a<=0 and b<=0):
            a=-a
            b=-b
        if (a<0 or b<0): continue
        g=gcd(a,b)
        if (g==0):continue
        a//=g
        b//=g
        t=1e100
        if (a>0):t=min(t,(yy-1)//a)
        if (b>0):t=min(t,(xx-1)//b)
        if (a*xx+b>0):t=min(t,n//(a*xx+b))
        if (t==1e100):continue
        a*=t
        b*=t
        if (a<(yy//10) or b<(xx/10)):continue
        tmp=a*xx+b
        ans=max(ans,tmp)
print(ans)

其实题解里的 O ( L 4 l o g L ) O(L^4logL) O(L4logL)有点假,
枚举 L 2 L^2 L2 g c d gcd gcd理论次数 l o g ( 1 0 L ) = L l o g L log(10^L)=LlogL log(10L)=LlogL,还有除法复杂度设为 O ( P ) O(P) O(P)
总复杂度是 O ( L 3 l o g L ⋅ P ) O(L^3logL\cdot P) O(L3logLP) P 暴力是 L 2 P暴力是L^2 P暴力是L2,应该可以做到 L l o g L LlogL LlogL,所以题解里说的复杂度应该是 O ( L 4 l o g 2 L ) O(L^4log^2L) O(L4log2L)
如果用 s t e i n stein stein算法求 g c d gcd gcd的话是比较严格的 O ( L 4 l o g L ) O(L^4logL) O(L4logL),因为只有除二和减法,都是 O ( L ) O(L) O(L)的,但会跑满,肯定很慢

回到正文,先贴式子 ( 1 0 y − k , k ⋅ 1 0 b − 1 ) (10^y-k,k\cdot 10^b-1) (10yk,k10b1)
如果 m i n ( x , y ) < 18 min(x,y)<18 min(x,y)<18做一次高精度除法以后就相当于普通 g c d gcd gcd了,复杂度 O ( P + l o g ( 1 0 18 ) ) O(P+log(10^{18})) O(P+log(1018))
否则假设 x > y x>y x>y,该式 = ( 1 0 y − k , k 2 ⋅ 1 0 x − y − 1 ) =(10^y-k,k^2\cdot10^{x-y}-1) =(10yk,k210xy1),如果把 x + y x+y x+y作为整体的话,每次都会减至少 18 18 18,否则会跳转上一种情况
总次数 200 / 18 < 12 200/18<12 200/18<12,抛开枚举的复杂度 O ( 12 P ) O(12P) O(12P),实际上比如 100 , 100 100,100 100,100这种情况是不可能出现的,我算他是 ( 100 + 100 ) / 18 (100+100)/18 (100+100)/18,实际只有一次
如果打个表,这个数不会超过 7 7 7(我没打,毛估估)
x < = y x<=y x<=y其实也一样,因为哪怕 k 12 k^{12} k12也是个无关紧要的数,远小于 1 0 18 10^{18} 1018
故总复杂度 O ( 12 ⋅ L 2 P ) O(12\cdot L^2P) O(12L2P),其实还远跑不满,这只是我用纯数学能证到的地步

回头一看发现傻逼了,根本不需要这么麻烦的证明
不妨令 x > y x>y x>y,若 x > 2 y x>2y x>2y,取模后 x x x规模一定减半
x < = 2 y x<=2y x<=2y,根据 ( 1 0 y − k , k ⋅ 1 0 b − 1 ) = ( 1 0 y − k , k 2 ⋅ 1 0 x − y − 1 ) (10^y-k,k\cdot 10^b-1)=(10^y-k,k^2\cdot10^{x-y}-1) (10yk,k10b1)=(10yk,k210xy1) x − y x-y xy后规模一定减半
也不用按 18 18 18来分块了,每次高精除的复杂度和长度是相关的(应该可以视作 P = L l o g L P=LlogL P=LlogL),
故总复杂度 O ( L 2 ⋅ ( L + L / 2 + L / 4 + . . . ) l o g L ) = O ( L 3 l o g L ) O(L^2\cdot (L+L/2+L/4+...)logL)=O(L^3logL) O(L2(L+L/2+L/4+...)logL)=O(L3logL)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值