1. 程式人生 > 其它 >BZOJ 3783 陶陶的難題 題解

BZOJ 3783 陶陶的難題 題解

\begin{split}
\sum^{R}_{x=L} x \left \lfloor \dfrac{Ax+C}{B} \right \rfloor & = \sum^{R}_{x=0} x \left \lfloor \dfrac{Ax+C}{B} \right \rfloor - \sum^{L-1}_{x=0} x \left \lfloor \dfrac{Ax+C}{B} \right \rfloor
\end{split}

然後直接跑裸的 類歐,求出兩個 $g$ 函式的值就行。

namespace LZX
{
    using namespace std;
    #define int long long
    #define i64 long long
    const int MOD=1e9+7;
    struct Euclid
    {
        i64 f,g,h;
        Euclid(){}
        Euclid(i64 ff,i64 gg,i64 hh):f(ff),g(gg),h(hh){}
    };
    int a,b,c,l,r;
    i64 i2,i6;
    i64 math_qpow(i64 base,i64 power,i64 mod)
    {
        i64 res=1;
        while(power)
        {
            if(power&1)
            {
                res=res*base%mod;
            }
            base=base*base%mod;
            power>>=1;
        }
        return res;
    }
    Euclid math_likeGCD(int n,int a,int b,int c)
    {
        int ac=a/c,bc=b/c,m=(a*n+b)/c,n1=n+1,n21=n*2+1;
        Euclid d,e;
        if(!a)
        {
            d.f=bc*n1%MOD;
            d.g=bc*n%MOD*n1%MOD*i2%MOD;
            d.h=bc*bc%MOD*n1%MOD;
            return d;
        }
        if(a>=c||b>=c)
        {
            d.f=n*n1%MOD*i2%MOD*ac%MOD+bc*n1%MOD;
            d.g=ac*n%MOD*n1%MOD*n21%MOD*i6%MOD+bc*n%MOD*n1%MOD*i2%MOD;
            d.h=ac*ac%MOD*n%MOD*n1%MOD*n21%MOD*i6%MOD+bc*bc%MOD*n1%MOD+ac*bc%MOD*n%MOD%MOD*n1%MOD;
            d.f%=MOD;
            d.g%=MOD;
            d.h%=MOD;
            e=math_likeGCD(n,a%c,b%c,c);
            d.h+=e.h+2*bc%MOD*e.f%MOD+2*ac%MOD*e.g%MOD;
            d.g+=e.g;
            d.f+=e.f;
            d.f%=MOD;
            d.g%=MOD;
            d.h%=MOD;
            return d;
        }
        e=math_likeGCD(m-1,c,c-b-1,a);
        d.f=n*m%MOD-e.f;
        d.f=(d.f%MOD+MOD)%MOD;
        d.g=n*m%MOD*n1%MOD-e.h-e.f;
        d.g=(d.g*i2%MOD+MOD)%MOD;
        d.h=n*m%MOD*(m+1)%MOD-2*e.g-2*e.f-d.f;
        d.h=(d.h%MOD+MOD)%MOD;
        return d;
    }
    int _main()
    {
        Euclid ansr,ansl;
        i2=math_qpow(2,MOD-2,MOD);
        i6=math_qpow(6,MOD-2,MOD);
        scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&l,&r);
        ansr=math_likeGCD(r,a,c,b);
        //cout<<__LINE__<<endl;
        ansl=math_likeGCD(l-1,a,c,b);
        //cout<<__LINE__<<endl;
        printf("%lld\n",((ansr.g-ansl.g)%MOD+MOD)%MOD);
        return 0;
    }
}