Euclid class study notes

effect

Actually find something about divisible and type, such as
\ [\ sum_ {i = 0 } ^ n \ lfloor \ frac {ai + b} {c} \ rfloor, \ sum_ {i = 0} ^ n \ lfloor \ AI + B} {FRAC {C} \ rfloor ^ 2, \ I = {0} sum_ ^ Ni \ lfloor \ FRAC AI + B} {} {C \ rfloor \]
(from example here three luoguP5170 )

While that name, but in fact nothing to do with gcd, but the complexity and the complexity of the analysis of the same. Complexity is therefore \ (O (\ log \ max (A, C)) \) .

The first formula is actually seeking in the first quadrant below the line integral points

ALGORITHM

Nothing thinking, is to push equation, using some basic math skills.

The above three formulas that the push needed Trick:
\ [\ lfloor \ FRAC AI + B} {} {C \ rfloor = \ lfloor \ FRAC {(A \ BMOD C) I + (B \ BMOD C)} {C} \ rfloor + i \ lfloor \ frac
{a} {c} \ rfloor + \ lfloor \ frac {b} {c} \ rfloor \\ X ^ 2 = 2 \ sum_ {d = 0} ^ nd-X \] first demonstrate a very good expression, a and b are simply put down into kc + r to form.

The second equation is eliminated by adding a quadratic summation, cubic empathy may eliminate a similar manner. After the exchange may be simplified by summing the sequence.

Such things considered divided into two categories: a b is greater than or equal to c; a and b is less than c.

\(a \ge c \ or \ b \ge c\)

Application of a recursion formula is easily from (a, b, c, n) to (a% c, b% c, c, n).

\(a,b < c\)

The Discovery \ (\ lfloor \ FRAC AI + B} {} {C \ rfloor \ n-Le \) , can use this narrow range. Order \ (m = \ lfloor \ FRAC {AN + B} {C} \ rfloor \) : \
[F (A, B, C, n-) = \ sum_ {I = 0} ^ n-\ lfloor \ FRAC {AI + b} {c} \ rfloor \\ = \ sum_ {i = 0} ^ n \ sum_ {d = 0} ^ {m-1} [\ lfloor \ frac {ai + b} {c} \ rfloor \ ge d + 1] \\ = \ sum_ {d = 0} ^ {m-1} \ sum_ {i = 0} ^ n [i> \ lfloor \ frac {cd + cb-1} {a} \ rfloor] \ \ = \ sum_ {d = 0 } ^ {m-1} n - \ lfloor \ frac {cd + cb-1} {a} \ rfloor \\ = n * m - f (c, cb-1, a, m-1) \]
key fact in the first step, the predicate is critical (actually \ (X-= \ sum_ {D} = ^. 1 the X1 \) ). The latter is very obviously a. He pushed a.
\ [G (a, b, c, n) = \ sum_ {i = 0} ^ n \ lfloor \ frac {ai + b} {c} \ rfloor ^ 2 \\ = \ sum_ {i = 0} ^ n2 \ sum_ {d = 1} ^ {\ lfloor \ frac {ai + b} {c} \ rfloor} d - \ lfloor \ frac {ai + b} {c} \ rfloor \\ = 2 \ sum_ {d = 0 } ^ {m-1} d + 1 \ sum_ {i = 0} ^ n [\ lfloor \ frac {ai + b} {c} \ rfloor \ ge d + 1] - f (a, b, c, d ) \ \]
here used the above-mentioned second formula. Others are similar, not repeat them.

application

luoguP5170

其中
\[ f=\sum_{i=0}^n\lfloor\frac{ai+b}{c}\rfloor , g=\sum_{i=0}^n\lfloor\frac{ai+b}{c}\rfloor^2 ,h= \sum_{i=0}^ni\lfloor\frac{ai+b}{c}\rfloor \]

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair<int,int> pii;
typedef pair<LL,int> pli;
const int SZ = 1e6 + 10;
const LL INF = 1e15 + 10;
const int mod = 998244353;
const LD eps = 1e-8;

LL read() {
    LL n = 0;
    char a = getchar();
    bool flag = 0;
    while(a > '9' || a < '0') { if(a == '-') flag = 1; a = getchar(); }
    while(a <= '9' && a >= '0') { n = n * 10 + a - '0',a = getchar(); }
    if(flag) n = -n;
    return n;
}


struct node {
    LL f,g,h;
};

struct LO {

    const LL inv2 = 499122177;
    const LL inv6 = 166374059;

    LL F1(LL n) {
        n %= mod;
        return n * (n+1) % mod * inv2 % mod;
    }

    LL F2(LL n) {
        n %= mod;
        return n * (n+1) % mod * (2*n+1) % mod * inv6 % mod;
    }

    node solve(LL a,LL b,LL c,LL n) {
        LL f,g,h;
        if(a == 0) {
            n %= mod;
            f = (b/c%mod) * (n+1) % mod;
            g = (b/c%mod) * (b/c%mod)%mod * (n+1) % mod;
            h = (b/c%mod) * F1(n) % mod;
        }
        else if(a>=c || b>=c) {
            node t = solve(a%c,b%c,c,n);
            f = (t.f + F1(n)*(a/c%mod)%mod + ((n+1)%mod)*(b/c%mod)%mod) % mod;
            g = (F2(n)*(a/c%mod)%mod*(a/c%mod)%mod + ((n+1)%mod)*(b/c%mod)%mod*(b/c%mod)%mod + t.g
                  + 2*F1(n)*(a/c%mod)%mod*(b/c%mod)%mod + 2*(a/c%mod)*t.h%mod + 2*(b/c%mod)*t.f%mod) % mod;
            h = (t.h + F2(n)*(a/c%mod)%mod + F1(n)*(b/c%mod)%mod) % mod;
        }
        else {
            LL m = (a*n+b)/c;
            node t = solve(c,c-b-1,a,m-1);
            m %= mod;
            f = (n*m%mod - t.f) % mod;
            g = (2*n*F1(m)%mod - 2*(t.h+t.f) - f) % mod;
            h = (F1(n)*m%mod - (t.g+t.f)*inv2%mod) % mod;
        }
        f += mod; f %= mod;
        g += mod; g %= mod;
        h += mod; h %= mod;
        return (node){f,g,h};
    }
}lo;

int main() {
    int T = read();
    while(T --) {
        LL n = read(),a = read(),b = read(),c = read();
        node ans = lo.solve(a,b,c,n);
        printf("%lld %lld %lld\n",ans.f,ans.g,ans.h);
    }
}

Guess you like

Origin www.cnblogs.com/dqsssss/p/11300850.html