1. 程式人生 > >[P5170] 類歐幾裏得算法

[P5170] 類歐幾裏得算法

turn 結構 times aligned res spl struct ali 如果

のすたの“類歐幾裏得算法”第二題 P5170

【題意】已知\(n,a,b,c\),求
\[ \begin{aligned} f_{1}(a,b,c,n)&=\sum_{i=0}^n\lfloor\dfrac{ai+b}{c}\rfloor\f_{2}(a,b,c,n)&=\sum_{i=0}^n\lfloor\dfrac{ai+b}{c}\rfloor^2\f_{3}(a,b,c,n)&=\sum_{i=0}^n\lfloor\dfrac{ai+b}{c}\rfloor*i\\end{aligned} \]
【預備】

\(m=\lfloor\dfrac{a\times n+b}{c}\rfloor,\ t_{1}=\lfloor\dfrac{a}{c}\rfloor,\ t_{2}=\lfloor\dfrac{b}{c}\rfloor\)

定義\([\text{expression}]\)為真值表達式。

簡單的引理,當\(a,b,c\in Z?\)

  • \(a\le\lfloor\dfrac{b}{c}\rfloor \Rightarrow ac\le b ?\)
  • \(a< bc \Rightarrow t_{1}<b\)

【限界】a=0時直接計算。

【式一】對原式變形
\[ f_{1}(a,b,c,n) =\sum_{i=0}^nt_{1}\times i+t_{2}+\lfloor\dfrac{(a\bmod c)\times i+(b\bmod c)}{c}\rfloor\=t_{1}\times\dfrac{n(n+1)}{2}+t_{2}\times(n+1)+ f_{1}(a\bmod c,b\bmod c,c,n) \]


\(t1=t2=0\)\(a<c\)\(b<c\)時,
\[ f_{1}(a,b,c,n)= \sum_{i=0}^n\sum_{j=1}^m [j\le\dfrac{ai+b}{c}] =\sum_{i=0}^n\sum_{j=1}^m [j\le\lfloor\dfrac{ai+b}{c}\rfloor]\=\sum_{j=1}^m\sum_{i=0}^n[j\le\lfloor\dfrac{ai+b}{c}\rfloor] =\sum_{j=1}^m\sum_{i=0}^n[cj-b\le ai] =\sum_{j=1}^m\sum_{i=0}^n[cj-b-1< ai]\=\sum_{j=1}^m\sum_{i=0}^n[\lfloor\dfrac{cj-b-1}{a}\rfloor< i] =\sum_{j=1}^m(n-\lfloor\dfrac{cj-b-1}{a}\rfloor)\=mn-\sum_{i=1}^m\lfloor\dfrac{ci-b-1}{a}\rfloor =mn-\sum_{i=0}^{m-1}\lfloor\dfrac{ci+c-b-1}{a}\rfloor\=mn-f_{1}(c,c-b-1,a,m-1) \]

【式二】對原式變形
\[ f_{2}(a,b,c,n) =\sum_{i=0}^n(t_{1}\times i+t_{2}+\lfloor\dfrac{(a\bmod c)\times i+(b\bmod c)}{c}\rfloor)^2\=\sum_{i=0}^n \begin{cases} (t_{1}\times i)^2+t_{2}^2+\lfloor\dfrac{(a\bmod c)\times i+(b\bmod c)}{c}\rfloor^2\ +2t_{1}t_{2}*i\ +2t_{1}i\lfloor\dfrac{(a\bmod c)\times i+(b\bmod c)}{c}\rfloor\ +2t_{2}\lfloor\dfrac{(a\bmod c)\times i+(b\bmod c)}{c}\rfloor \end{cases}\=\begin{cases} t_{1}^2\sum_{i=0}^ni^2+t_{2}^2*(n+1)+f_{2}(a\bmod c,b\bmod c,c,n)\ +2t_{1}t_{2}\sum_{i=0}^n i\ +2t_{1}f_{3}(a\bmod c,b \bmod c,c,n)\ +2t_{2}f_{1}(a\bmod c,b \bmod c,c,n) \end{cases}\\]

\(t1=t2=0\)\(a<c\)\(b<c?\)時,
\[ f_{2}(a,b,c,d)= \sum_{i=0}^n\lfloor\dfrac{ai+b}{c}\rfloor =\sum_{i=0}^n\sum_{j=1}^m\sum_{k=1}^m[\lfloor\dfrac{cj-b-1}{a}\rfloor< i\text{ and }\lfloor\dfrac{ck-b-1}{a}\rfloor< i]\=\sum_{i=0}^n\sum_{j=1}^m\sum_{k=1}^m [\max(\lfloor\dfrac{cj-b-1}{a}\rfloor,\lfloor\dfrac{ck-b-1}{a}\rfloor)< i]\=\sum_{j=1}^m\sum_{k=1}^m \sum_{i=0}^n[\max(\lfloor\dfrac{cj-b-1}{a}\rfloor,\lfloor\dfrac{ck-b-1}{a}\rfloor)< i]\=\sum_{j=1}^m\sum_{k=1}^m n-\max(\lfloor\dfrac{cj-b-1}{a}\rfloor,\lfloor\dfrac{ck-b-1}{a}\rfloor)\=nm^2-\sum_{j=1}^m\sum_{k=1}^m\max(\lfloor\dfrac{cj-b-1}{a}\rfloor,\lfloor\dfrac{ck-b-1}{a}\rfloor)\=nm^2-2*\sum_{j=1}^m\lfloor\dfrac{cj-b-1}{a}\rfloor*(j-1)-\sum_{j=1}^m \lfloor\dfrac{cj-b-1}{a}\rfloor\=nm^2-\sum_{j=0}^{m-1} \lfloor\dfrac{cj+c-b-1}{a}\rfloor*j-\sum_{j=0}^{m-1} \lfloor\dfrac{cj+c-b-1}{a}\rfloor\=nm^2-f_{1}(c,c-b-1,a,m-1)-2*f_{3}(c,c-b-1,a,m-1) \]

【式三】對原式變形
\[ f_{3}(a,b,c,n)=\sum_{i=0}^n\lfloor\dfrac{ai+b}{c}\rfloor*i =\sum_{i=0}^n (t_{1}\times i+t_{2}+\lfloor\dfrac{(a\bmod c)\times i+(b\bmod c)}{c}\rfloor)*i\=\sum_{i=0}^n t_{1}\times i^2+t_{2}\times i+\lfloor\dfrac{(a\bmod c)\times i+(b\bmod c)}{c}\rfloor\times i\=t_{1}\sum_{i=0}^ni^2+t_{2}\sum_{i=0}^ni+f_{3}(a\bmod c,b\bmod c,c,n) \]
\(t1=t2=0\)\(a<c\)\(b<c\)時,定義\(p(j)=\lfloor\dfrac{cj-b-1}{a}\rfloor\)
\[ f3(a,b,c,d) =\sum_{i=0}^n\sum_{j=1}^m [j\le\lfloor\dfrac{ai+b}{c}\rfloor]*i =\sum_{j=1}^m\sum_{i=0}^n[\lfloor\dfrac{cj-b-1}{a}\rfloor< i]*i\=\sum_{j=1}^m\sum_{i=p(j)+1}^ni =\sum_{j=1}^m \dfrac{1}{2}(p(j)+1+n)(n-p(j))\=\sum_{j=1}^m \dfrac{1}{2}(n\times p(j)-p^2(j)+n-p(j)+n^2-n\times p(j))\=\sum_{j=1}^m \dfrac{1}{2}(-p^2(j)+n-p(j)+n^2)\=\dfrac{-f_{2}(c,c-b-1,a,m-1)-f_{1}(c,c-b-1,a,m-1)+nm+n^2m}{2} \]
【時間復雜度】如果每個都單獨搜索的話,大概因該會炸吧。。考慮到三個函數的遞歸模式都很**,幹脆用一個結構體存下三個值。再參考第一題的分析,狀態數目是\(\log\)級別的。

#include <bits/stdc++.h>
#define LL long long 
using namespace std;
const LL mod=998244353;
const LL I2=499122177;
const LL I6=166374059;

inline LL s1(LL n) {return I2*n%mod*(n+1)%mod;}
inline LL s2(LL n) {return I6*n%mod*(n+1)%mod*(n+n+1)%mod;}

struct node {
    LL f1,f2,f3;
    node(LL f1=0,LL f2=0,LL f3=0):f1(f1),f2(f2),f3(f3){
//      assert(0<=f1 && 0<=f2 && 0<=f3);
//      assert(f1<mod && f2<mod && f3<mod);
    } 
};
node dfs(LL a,LL b,LL c,LL n) {
    if(!a||!n) return node(
        (b/c)*(n+1)%mod,
        (b/c)*(b/c)%mod*(n+1)%mod,
        (b/c)*s1(n)%mod
    );
    if(a>=c || b>=c) {
        LL t1=a/c, t2=b/c;
        node tmp=dfs(a%c,b%c,c,n);
        return node(
            (t1*s1(n)%mod+t2*(n+1)%mod+tmp.f1)%mod,
            (t1*t1%mod*s2(n)%mod
                +t2*t2%mod*(n+1)%mod
                +tmp.f2
                +2*t1%mod*t2%mod*s1(n)%mod
                +2*t1%mod*tmp.f3%mod
                +2*t2%mod*tmp.f1%mod
            )%mod,
            (t1*s2(n)%mod+t2*s1(n)%mod+tmp.f3)%mod
        );
    } else {
        LL m=(a*n+b)/c;
        node tmp=dfs(c,c-b-1,a,m-1);
        return node(
            (n*m%mod-tmp.f1+mod)%mod,
            (n*m%mod*m%mod-tmp.f1-2*tmp.f3%mod+mod+mod)%mod,
            (n*m%mod+n*n%mod*m%mod-tmp.f1-tmp.f2+mod+mod)%mod*I2%mod
        );
    }
} 

int main() {
    int T,a,b,c,n;
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d%d%d",&n,&a,&b,&c);
        node tmp=dfs(a,b,c,n);
        printf("%lld %lld %lld\n",tmp.f1,tmp.f2,tmp.f3) ;
    }
    return 0;
}

[P5170] 類歐幾裏得算法