【算法讲28:类欧几里得算法求和】洛谷 P5170

这篇博客介绍了如何利用类欧几里得算法解决一类求和问题,涉及f(a,b,c,n)、g(a,b,c,n)和h(a,b,c,n)三个函数的推导及优化。通过递归和边界条件处理,实现了复杂度的降低,但原始实现仍导致超时(TLE),最后提出了结构体优化方案,将时间复杂度降至O(Tlogn)。
摘要由CSDN通过智能技术生成

引入

  • 给定 n , a , b , c n,a,b,c n,a,b,c,求
    ∑ i = 0 n ⌊ a i + b c ⌋ ∑ i = 0 n ⌊ a i + b c ⌋ 2 ∑ i = 0 n i ⌊ a i + b c ⌋ \sum_{i=0}^n\Big\lfloor \frac{ai+b}{c} \Big\rfloor \\ \sum_{i=0}^n\Big\lfloor \frac{ai+b}{c} \Big\rfloor^2 \\ \sum_{i=0}^n i\Big\lfloor \frac{ai+b}{c} \Big\rfloor \\ i=0ncai+bi=0ncai+b2i=0nicai+b
  • 样例数 1 ≤ T ≤ 1 0 5 1\le T\le 10^5 1T105
    0 ≤ n , a , b , c ≤ 1 0 9 0\le n,a,b,c\le 10^9 0n,a,b,c109

记号

  • 我们记一下这三个函数
    f ( a , b , c , n ) = ∑ i = 0 n ⌊ a i + b c ⌋ h ( a , b , c , n ) = ∑ i = 0 n ⌊ a i + b c ⌋ 2 g ( a , b , c , n ) = ∑ i = 0 n i ⌊ a i + b c ⌋ f(a,b,c,n)=\sum_{i=0}^n\Big\lfloor \frac{ai+b}{c} \Big\rfloor\\ h(a,b,c,n)=\sum_{i=0}^n\Big\lfloor \frac{ai+b}{c} \Big\rfloor^2\\ g(a,b,c,n)=\sum_{i=0}^n i\Big\lfloor \frac{ai+b}{c} \Big\rfloor \\ f(a,b,c,n)=i=0ncai+bh(a,b,c,n)=i=0ncai+b2g(a,b,c,n)=i=0nicai+b

f ( a , b , c , n ) f(a,b,c,n) f(a,b,c,n) 的推导

  • a ≥ c a\ge c ac b ≥ c b \ge c bc 时,我们有
    f ( a , b , c , n ) = ∑ i = 0 n ⌊ ( a − a   m o d   c ) ∗ i + ( a   m o d   c ) ∗ i + b c ⌋ = f ( a % c , b % c , c , n ) + n ( n + 1 ) 2 ⌊ a c ⌋ + ( n + 1 ) ⌊ b c ⌋ \begin{aligned} f(a,b,c,n)&=\sum_{i=0}^n \Big \lfloor \frac{(a - a \bmod c)*i + (a \bmod c) * i + b}{c} \Big \rfloor\\ &=f(a\%c,b\%c,c,n)+\frac{n(n+1)}{2} \lfloor\frac{a}{c}\rfloor + (n+1)\lfloor\frac{b}{c}\rfloor \end{aligned} f(a,b,c,n)=i=0nc(aamodc)i+(amodc)i+b=f(a%c,b%c,c,n)+2n(n+1)ca+(n+1)cb
  • a < c a < c a<c b < c b < c b<c 时,设 m = ⌊ a n + b c ⌋ m=\lfloor\frac{an+b}{c}\rfloor m=can+b
    f ( a , b , c , n ) = ∑ i = 0 n ∑ j = 1 m [ ⌊ a i + b c ⌋ ≥ j ] = ∑ i = 0 n ∑ j = 0 m − 1 [ ⌊ a i + b c ⌋ ≥ j + 1 ] = ∑ i = 0 n ∑ j = 0 m − 1 [ i > j c + c − b − 1 a ] = ∑ j = 0 m − 1 n − ⌊ j c + c − b − 1 a ⌋ = n m − f ( c , c − b − 1 , a , m − 1 ) \begin{aligned} f(a,b,c,n)&=\sum_{i=0}^n\sum_{j=1}^m\Big[ \lfloor \frac{ai+b}{c} \rfloor \ge j\Big]\\ &=\sum_{i=0}^n\sum_{j=0}^{m-1}\Big[ \lfloor \frac{ai+b}{c} \rfloor \ge j+1\Big]\\ &=\sum_{i=0}^n\sum_{j=0}^{m-1}\Big[ i > \frac{jc+c-b-1}{a}\Big]\\ &=\sum_{j=0}^{m-1}n-\Big\lfloor \frac{jc+c-b-1}{a} \Big\rfloor\\ &=nm-f(c,c-b-1,a,m-1) \end{aligned} f(a,b,c,n)=i=0nj=1m[cai+bj]=i=0nj=0m1[cai+bj+1]=i=0nj=0m1[i>ajc+cb1]=j=0m1najc+cb1=nmf(c,cb1,a,m1)
    边界条件 a = 0 a=0 a=0

g ( a , b , c , n ) g(a,b,c,n) g(a,b,c,n) 的式子

  • a ≥ c a\ge c ac b ≥ c b \ge c bc 时,有
    g ( a , b , c , n ) = g ( a % c , b % c , c , n ) + n ( n + 1 ) ( 2 n + 1 ) / 6 ⌊ a c ⌋ + n ( n + 1 ) / 2 ⌊ b c ⌋ \begin{aligned} g(a,b,c,n)&=g(a\%c,b\%c,c,n)+n(n+1)(2n+1)/6 \lfloor\frac{a}{c}\rfloor\\ &+n(n+1)/2 \lfloor\frac{b}{c}\rfloor \end{aligned} g(a,b,c,n)=g(a%c,b%c,c,n)+n(n+1)(2n+1)/6ca+n(n+1)/2cb
  • a < c a < c a<c b < c b < c b<c 时,有
    g ( a , b , c , n ) = m n ( n + 1 ) − f ( c , c − b − 1 , a , m − 1 ) − h ( c , c − b − a , a , m − 1 ) 2 \begin{aligned} g(a,b,c,n)&=\frac{mn(n+1)-f(c,c-b-1,a,m-1)-h(c,c-b-a,a,m-1)}{2} \end{aligned} g(a,b,c,n)=2mn(n+1)f(c,cb1,a,m1)h(c,cba,a,m1)

h ( a , b , c , n ) h(a,b,c,n) h(a,b,c,n) 的式子

  • a ≥ c a\ge c ac b ≥ c b \ge c bc 时,得到:
    h ( a , b , c , n ) = h ( a % c , b % c , c , n ) + n ( n + 1 ) ( 2 n + 1 ) 6 ⌊ a c ⌋ 2 + 2 ⌊ b c ⌋ f ( a % c , b % c , c , n ) + 2 ⌊ a c ⌋ g ( a % c , b % c , c , n ) + ⌊ a c ⌋ ⌊ b c ⌋ n ( n + 1 ) + ⌊ b c ⌋ 2 ( n + 1 ) \begin{aligned} h(a,b,c,n)&=h(a\%c,b\%c,c,n)+\frac{n(n+1)(2n+1)}{6}\lfloor\frac{a}{c}\rfloor^2\\ &+2\lfloor\frac{b}{c}\rfloor f(a\%c,b\%c,c,n)\\ &+2\lfloor\frac{a}{c}\rfloor g(a\%c,b\%c,c,n)\\ &+\lfloor\frac{a}{c}\rfloor\lfloor\frac{b}{c}\rfloor n(n+1)\\ &+\lfloor\frac{b}{c}\rfloor^2(n+1) \end{aligned} h(a,b,c,n)=h(a%c,b%c,c,n)+6n(n+1)(2n+1)ca2+2cbf(a%c,b%c,c,n)+2cag(a%c,b%c,c,n)+cacbn(n+1)+cb2(n+1)
  • a < c a < c a<c b < c b < c b<c
    h ( a , b , c , n ) = m ( m + 1 ) n − 2 g ( c , c − b − 1 , a , m − 1 ) − 2 f ( c , c − b − 1 , a , m − 1 ) − f ( a , b , c , n ) \begin{aligned} h(a,b,c,n)&=m(m+1)n-2g(c,c-b-1,a,m-1)\\ &-2f(c,c-b-1,a,m-1)\\ &-f(a,b,c,n) \end{aligned} h(a,b,c,n)=m(m+1)n2g(c,cb1,a,m1)2f(c,cb1,a,m1)f(a,b,c,n)

回到题目上来

  • 然后把式子一放,总能过了吧?
ll f(ll,ll,ll,ll);      //   floor[ (ai+b)/c ]
ll g(ll,ll,ll,ll);      // i floor[ (ai+b)/c ]
ll h(ll,ll,ll,ll);      // [ floor[ (ai+b)/c ] ]^2


ll f(ll a,ll b,ll c,ll n){
    if(a == 0)
        return (n + 1) * (b / c) % MOD;
    if(a >= c || b >= c){
        return (f(a%c,b%c,c,n) + n * (n + 1) % MOD * iv2 % MOD * (a / c) + (n + 1) * (b / c) % MOD) % MOD;
    }else{
        ll m = (a * n + b) / c;
        return (n * m % MOD - f(c,c-b-1,a,m-1) + MOD) % MOD;
    }
}


ll g(ll a,ll b,ll c,ll n){
    if(a == 0)
        return n * (n + 1) % MOD * iv2 % MOD * (b/c) % MOD;
    if(n == 0)return 0;
    if(a >= c || b >= c){
        return (g(a%c,b%c,c,n) + n * (n + 1) % MOD * (2*n+1) % MOD * iv6 % MOD * (a/c) % MOD + n * (n + 1) % MOD * iv2 % MOD * (b/c) % MOD ) % MOD;
    }else{
        ll m = (a * n + b) / c;
        return (n * m % MOD * (n + 1) % MOD - f(c,c-b-1,a,m-1) - h(c,c-b-1,a,m-1) + 2 * MOD) % MOD * iv2 % MOD;
    }
}

ll h(ll a,ll b,ll c,ll n){
    if(a == 0)
        return (n+1) * (b/c) % MOD * (b/c) % MOD;
    if(n == 0)return (b/c) * (b/c) % MOD;
    if(a >= c || b >= c){
        return (h(a%c,b%c,c,n) + n * (n + 1) % MOD * (2*n+1) % MOD * iv6 % MOD * (a/c) % MOD * (a/c) % MOD + 2 * (b / c) % MOD * f(a%c,b%c,c,n) % MOD + 2 * (a / c) % MOD * g(a%c,b%c,c,n) % MOD + (a/c) * (b/c) % MOD * n % MOD * (n+1) % MOD + (b/c) * (b/c) % MOD * (n + 1) % MOD ) % MOD;
    }else{
        ll m = (a * n + b) / c;
        return (n * m % MOD * (m + 1) % MOD - 2 * g(c,c-b-1,a,m-1) - 2 * f(c,c-b-1,a,m-1) - f(a,b,c,n)) % MOD;
    }
}
  • 结果不大行,都 T L E \color{red}TLE TLE 了,得优化一下
    我们用一个结构体去存 Q u e r y { F , G , H } Query\{F,G,H\} Query{F,G,H} 表示目前的 f ( a , b , c , n ) , g ( a , b , c , n ) , h ( a , b , c , n ) f(a,b,c,n),g(a,b,c,n),h(a,b,c,n) f(a,b,c,n),g(a,b,c,n),h(a,b,c,n) 的值
    然后就变成了这样:
    时间复杂度: O ( T log ⁡ n ) O(T\log n) O(Tlogn)
struct Query{
    ll f,g,h;
};
Query solve(ll a,ll b,ll c,ll n){
    Query ans,tmp;
    if(a == 0){
        ans.f = (n + 1) * (b / c) % MOD;
        ans.g = n * (n + 1) % MOD * iv2 % MOD * (b/c) % MOD;
        ans.h = (n+1) * (b/c) % MOD * (b/c) % MOD;
        return ans;
    }
    if(a >= c || b >= c){
        tmp = solve(a % c,b % c,c,n);
        ans.f = (tmp.f + (a / c) * n % MOD * (n + 1) % MOD * iv2 % MOD + (b / c) * (n + 1) % MOD) % MOD;
        ans.g = (tmp.g + (a / c) * n % MOD * (n + 1) % MOD * (2 * n + 1) % MOD * iv6 % MOD + (b / c) * n % MOD * (n + 1) % MOD * iv2 % MOD) % MOD;
        ans.h = ((a / c) * (a / c) % MOD * n % MOD * (n + 1) % MOD * (2 * n + 1) % MOD * iv6 % MOD +
                (b / c) * (b / c) % MOD * (n + 1) % MOD + (a / c) * (b / c) % MOD * n % MOD * (n + 1) % MOD +
                tmp.h + 2 * (a / c) % MOD * tmp.g % MOD + 2 * (b / c) % MOD * tmp.f % MOD) % MOD;
        return ans;
    }
    ll m = (a * n + b) / c;
    tmp = solve(c,c-b-1,a,m-1);
    ans.f = (n * (m % MOD) % MOD - tmp.f) % MOD;
    ans.g = (n * (n + 1) % MOD * (m % MOD) % MOD - tmp.f - tmp.h) % MOD * iv2 % MOD;
    ans.h = (n * (m % MOD) % MOD * ((m + 1) % MOD) % MOD - 2 * tmp.g - 2 * tmp.f - ans.f) % MOD;
    return ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值