学习心得 - 类欧

· · 算法·理论

今天做到了 ABC402 G,学习一下哈。

【SX/NOI-】类欧

类欧的名字是因为这个算法类似于辗转相除,其实就是复杂度计算而已。

其他没什么关系了。

这个算法主要是求在一条直线下的整点有多少个。

按照例题,它当然可以用来求:

f(a,b,c,n)=\sum_{i=0}^n\lfloor \frac{ai+b}{c}\rfloor \\ g(a,b,c,n)= \sum_{i=0}^n\lfloor \frac{ai+b}{c}\rfloor^2 \\ h(a,b,c,n)=\sum_{i=0}^ni\lfloor \frac{ai+b}{c}\rfloor

算法推理 f 函数

我们注意到 a\ge cb\ge c 时显然可以直接除掉多余部分。

可以变为

\begin{aligned} f(a,b,c,n) &=\sum_{i=0}^n\lfloor\frac{i(a\bmod c)+(b\bmod c)}{c}\rfloor+i\lfloor\frac{a}{c}\rfloor+\lfloor \frac{b}{c} \rfloor \\ &=f(a\bmod c,b\bmod 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)=\sum_{i=0}^n\sum_{j=1}^{\lfloor \frac{an+b}{c}\rfloor}[j\leq\lfloor \frac{ai+b}{c}\rfloor]

考虑整理第二层。

\begin{aligned} \sum_{j=1}^{\lfloor \frac{an+b}{c}\rfloor}[j\leq\lfloor \frac{ai+b}{c}\rfloor]&=\sum_{j=0}^{\lfloor \frac{an+b}{c}\rfloor-1}[jc+c<{ai+b}+1]\\ &=\sum_{j=0}^{\lfloor \frac{an+b}{c}\rfloor-1}[jc+c-b-1<ai]\\ \end{aligned}

我们知道 \sum 是可以调换的。

考虑调换。

\begin{aligned} f(a,b,c,n) &=\sum_{j=0}^{\lfloor \frac{an+b}{c}\rfloor-1}\sum_{i=0}^n[jc+c-b-1<ai]\\ &=\sum_{j=0}^{\lfloor \frac{an+b}{c}\rfloor-1}\sum_{i=0}^n[i>\lfloor\frac{jc+c-b-1}{a}\rfloor]\\ &=\sum_{j=0}^{\lfloor \frac{an+b}{c}\rfloor-1}n-\lfloor\frac{jc+c-b-1}{a}\rfloor\\ &=n{\lfloor \frac{an+b}{c}\rfloor}-f(c,c-b-1,a,{\lfloor \frac{an+b}{c}\rfloor}-1) \end{aligned}

ok 在你头晕之前我们总结出一个类似辗转相除的式子。

这里少了个 a=0 应该直接带入就看得懂吧。

f(a,b,c,n)= \begin{cases} (n+1)\lfloor{\frac{b}{c}}\rfloor & a=0 \\ f(a\bmod c,b\mod c,c,n)+\frac{n(n+1)}{2}\lfloor\frac{a}{c}\rfloor+(n+1)\lfloor \frac{b}{c} \rfloor & a\ge c\vee b\ge c \\ n{\lfloor \frac{an+b}{c}\rfloor}-f(c,c-b-1,a,{\lfloor \frac{an+b}{c}\rfloor}-1) & otherwise \end{cases}

这就是我们最后归纳的式子。

算法推理 g,h 函数

同理,a=0

g(a,b,c,n)=(n+1)\lfloor\frac{b}{c}\rfloor^2 \\ h(a,b,c,n)=\frac{n(n+1)}{2}\lfloor\frac{b}{c}\rfloor

然后是 a\ge c \vee b\ge c

这个贼乱,分开来打。

先看 g

\begin{aligned} g(a,b,c,n) &=\sum_{i=0}^n(\lfloor\frac{i(a\bmod c)+(b\bmod c)}{c}\rfloor+i\lfloor\frac{a}{c}\rfloor+\lfloor \frac{b}{c} \rfloor)^2 \\ &=\sum_{i=0}^n(\lfloor\frac{i(a\bmod c)+(b\bmod c)}{c}\rfloor)^2+2(\lfloor\frac{i(a\bmod c)+(b\bmod c)}{c}\rfloor)(i\lfloor\frac{a}{c}\rfloor+\lfloor \frac{b}{c}\rfloor)+({i\lfloor\frac{a}{c}\rfloor+\lfloor \frac{b}{c}} \rfloor)^2 \\ &=\sum_{i=0}^n(\lfloor\frac{i(a\bmod c)+(b\bmod c)}{c}\rfloor)^2+2\sum_{i=0}^n(\lfloor\frac{i(a\bmod c)+(b\bmod c)}{c}\rfloor)(i\lfloor\frac{a}{c}\rfloor+\lfloor \frac{b}{c}\rfloor)+\sum_{i=0}^n({i\lfloor\frac{a}{c}\rfloor+\lfloor \frac{b}{c}} \rfloor)^2 \\ &=g(a \bmod c,b \bmod c,c,n)+2\lfloor \frac{a}{c} \rfloor h(a \bmod c,b \bmod c,c,n)+2\lfloor \frac{b}{c} \rfloor f(a \bmod c,b \bmod c,c,n)+\sum_{i=0}^n(\lfloor i\frac{a}{c}\rfloor)^2+2i\lfloor\frac{a}{c}\rfloor \lfloor\frac{b}{c}\rfloor+\lfloor\frac{b}{c}\rfloor^2 \\ &=g(a \bmod c,b \bmod c,c,n)+2\lfloor \frac{a}{c} \rfloor h(a \bmod c,b \bmod c,c,n)+2\lfloor \frac{b}{c} \rfloor f(a \bmod c,b \bmod c,c,n)+\frac{n(n+1)(2n+1)}{6}{\lfloor \frac{a}{c}\rfloor}^2+n(n+1)\lfloor\frac{a}{c}\rfloor\lfloor\frac{b}{c}\rfloor+(n+1)\lfloor\frac{b}{c}\rfloor^2 \end{aligned}

神经中枢爆炸......

h,看起来简单多了 /ll。

\begin{aligned} h(a,b,c,n) &=\sum_{i=0}^n i\lfloor \frac{i(a\bmod c)+b\bmod c}{c} \rfloor+i(i\lfloor \frac{a}{c} \rfloor+\lfloor \frac{b}{c}\rfloor)\\ &=h(a\bmod c,b\bmod c,c,n)+\sum_{i=0}^n i^2\lfloor \frac{a}{c} \rfloor+i\lfloor \frac{b}{c}\rfloor\\ &=h(a\bmod c,b\bmod c,c,n)+\frac{n(n+1)(2n+1)}{6}\lfloor \frac{a}{c} \rfloor+\frac{n(n+1)}{2}\lfloor \frac{b}{c} \rfloor \end{aligned}

接下来是分析其他情况。

先来 g

\begin{aligned} g(a,b,c,n) &=2\sum_{i=0}^n\sum_{j=1}^{\lfloor \frac{ai+b}{c}\rfloor}j-\sum_{i=0}^n{\lfloor \frac{ai+b}{c}\rfloor}\\ &=(2\sum_{i=0}^n\sum_{j=1}^{{\lfloor \frac{an+b}{c}\rfloor}}j[j\leq {\lfloor \frac{ai+b}{c}\rfloor}])-f(a,b,c,n)\\ &=(2\sum_{i=0}^n\sum_{j=0}^{{\lfloor \frac{an+b}{c}\rfloor}-1}(j+1)[jc+c-1<ai+b])-f(a,b,c,n)\\ &=(2\sum_{j=0}^{{\lfloor \frac{an+b}{c}\rfloor}-1}(j+1)\sum_{i=0}^n[jc+c-1<ai+b])-f(a,b,c,n)\\ &=(2\sum_{j=0}^{{\lfloor \frac{an+b}{c}\rfloor}-1}(j+1)\sum_{i=0}^n[i>\lfloor\frac{jc+c+b-1}{a}\rfloor])-f(a,b,c,n)\\ &=(2\sum_{j=0}^{{\lfloor \frac{an+b}{c}\rfloor}-1}(j+1)(n-\lfloor\frac{jc+c+b-1}{a}\rfloor))-f(a,b,c,n)\\ &=n{\lfloor \frac{an+b}{c}\rfloor}({\lfloor \frac{an+b}{c}\rfloor}+1)-f(a,b,c,n)-2h(c,c-b-1,a,{\lfloor \frac{an+b}{c}\rfloor}-1)-2f(c,c-b-1,a,{\lfloor \frac{an+b}{c}\rfloor}-1)\\ \end{aligned}

脑子炸掉的同学可以先做模板题的前两问。

相对简单的是 h

\begin{aligned} h(a,b,c,n) &=\sum_{i=0}^n i \sum_{j=1}^{\lfloor \frac{an+b}{c}\rfloor}[j\leq {\lfloor \frac{ai+b}{c}\rfloor}]\\ &=\sum_{i=0}^n i \sum_{j=0}^{\lfloor \frac{an+b}{c}\rfloor-1}[jc+c-1<ai+b]\\ &=\sum_{j=0}^{\lfloor \frac{an+b}{c}\rfloor-1}\sum_{i=0}^n i[i>\lfloor \frac{jc+c-b-1}{a} \rfloor]\\ &=\sum_{j=0}^{{\lfloor \frac{an+b}{c}\rfloor-1}}\frac{n(n+1)}{2}-\sum_{i=0}^{\lfloor \frac{jc+c-b-1}{a} \rfloor}i\\ &=\sum_{j=0}^{{\lfloor \frac{an+b}{c}\rfloor-1}}\frac{n(n+1)}{2}-\frac{{\lfloor \frac{jc+c-b-1}{a} \rfloor}({\lfloor \frac{jc+c-b-1}{a} \rfloor}+1)}{2}\\ &=\sum_{j=0}^{{\lfloor \frac{an+b}{c}\rfloor-1}}\frac{n(n+1)}{2}-\frac{{\lfloor \frac{jc+c-b-1}{a} \rfloor}({\lfloor \frac{jc+c-b-1}{a} \rfloor}+1)}{2}\\ &=\frac{{\lfloor \frac{an+b}{c}\rfloor}n(n+1)-g(c,c-b-1,a,{\lfloor \frac{an+b}{c}\rfloor}-1)-f(c,c-b-1,a,{\lfloor \frac{an+b}{c}\rfloor}-1)}{2} \end{aligned}

我们总结一下哈:

g(a,b,c,n)= \begin{cases} (n+1)\lfloor{\frac{b}{c}}\rfloor^2 & a=0 \\ g(a \bmod c,b \bmod c,c,n)+2\lfloor \frac{a}{c} \rfloor h(a \bmod c,b \bmod c,c,n)+2\lfloor \frac{b}{c} \rfloor f(a \bmod c,b \bmod c,c,n)+\frac{n(n+1)(2n+1)}{6}{\lfloor \frac{a}{c}\rfloor}^2+n(n+1)\lfloor\frac{a}{c}\rfloor\lfloor\frac{b}{c}\rfloor+(n+1)\lfloor\frac{b}{c}\rfloor^2 & a\ge c\vee b\ge c \\ n{\lfloor \frac{an+b}{c}\rfloor}({\lfloor \frac{an+b}{c}\rfloor}+1)-f(a,b,c,n)-2h(c,c-b-1,a,{\lfloor \frac{an+b}{c}\rfloor}-1)-2f(c,c-b-1,a,{\lfloor \frac{an+b}{c}\rfloor}-1) & otherwise \end{cases} h(a,b,c,n)= \begin{cases} \frac{n(n+1)}{2}\lfloor\frac{b}{c}\rfloor & a=0 \\ h(a\bmod c,b\bmod c,c,n)+\frac{n(n+1)(2n+1)}{6}\lfloor \frac{a}{c} \rfloor+\frac{n(n+1)}{2}\lfloor \frac{b}{c} \rfloor & a\ge c\vee b\ge c \\ \frac{{\lfloor \frac{an+b}{c}\rfloor}n(n+1)-g(c,c-b-1,a,{\lfloor \frac{an+b}{c}\rfloor}-1)-f(c,c-b-1,a,{\lfloor \frac{an+b}{c}\rfloor}-1)}{2}& otherwise \end{cases}

你肯定已经崩溃了 qwq。

那你还看模板题代码吗

#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct func{
    ll f,g,h;
}res;
const ll  p=998244353,p2=499122177,p6=166374059;
func solve(ll n,ll a,ll b,ll c){
    func ans,nxt;
    if(a==0){
        ans.f=(b/c)*(n+1)%p;
        ans.g=(b/c)*(b/c)%p*(n+1)%p;
        ans.h=(b/c)*n%p*(n+1)%p*p2%p;
    }else if(a>=c||b>=c){
        nxt=solve(n,a%c,b%c,c);
        ans.f=(nxt.f+n*(n+1)%p*p2%p*(a/c)%p+(n+1)*(b/c)%p)%p;
        ans.g=(nxt.g+(a/c)*(a/c)%p*n%p*(n+1)%p*(2*n+1)%p*p6%p+(n+1)*(b/c)%p*(b/c)%p+2*(a/c)%p*nxt.h%p+2*(b/c)%p*nxt.f%p+2*(a/c)%p*(b/c)%p*n%p*(n+1)%p*p2%p)%p;
        ans.h=((a/c)*n%p*(n+1)%p*(2*n+1)%p*p6%p+(b/c)*n%p*(n+1)%p*p2%p+nxt.h)%p;
    }else{
        ll m=(a*n+b)/c,pm=m%p;
        nxt=solve(m-1,c,c-b-1,a);
        ans.f=(n*pm%p-nxt.f)%p;
        ans.g=(n*pm%p*((m+1)%p)%p-2*nxt.h-2*nxt.f-ans.f+p)%p;
        ans.h=(n*(n+1)%p*pm%p-nxt.f-nxt.g)%p*p2%p;
    }
    return ans;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--){
        ll n,a,b,c;
        cin>>n>>a>>b>>c;
        res=solve(n,a,b,c);
        cout<<(res.f+p)%p<<" "<<(res.g+p)%p<<" "<<(res.h+p)%p<<"\n";
    }
    return 0;
}

【NOI/NOI+/CTSC】ABC402G

在上面 7500+ 字之后,我们进入正题(

本质求

\frac{a^2n(n+1)(2n+1)}{6}+\frac{a(b_1+b_2)n(n+1)}{2}+(n+1)b_1b_2+\frac{c^2(g(n,a,b_1,c)+g(n,a,b_2,c)-f(n,a,b_1,c)+f(n,a,b_2,c))}{2}-c[a(h(n,a,b_1,c)+h(n,a,b_2,c))+b_1f(n,a,b_2,c)+b_2f(n,a,b_1,c)]

推式子的部分以后再补充。

【NOI/NOI+/CTSC】ABC283Ex

upd 2025/05/17.

人生中第一道 Ex 题!

本质求

\sum_{i=0}^{30 } f(\lfloor \frac{n-r}{m}\rfloor,m,r,2^i)-2f(\lfloor \frac{n-r}{m}\rfloor,m,r,2^{i+1})

为什么呢?看原式。

\begin{aligned} \sum_{i\bmod m=r}^n \operatorname{pc}(i) &=\sum_{i\bmod m=r}^n \sum_{j=0}^{30} [\lfloor \frac{i}{2^j}\rfloor\bmod 2=1] \\ &=\sum_{j=0}^{30}\sum_{i\bmod m=0}^{n-r} [\lfloor \frac{i+r}{2^j}\rfloor\bmod 2=1] \\ &=\sum_{j=0}^{30}\sum_{i=0}^{\lfloor \frac{n-r}{m}\rfloor} [\lfloor\frac{im+r}{2^j}\rfloor\bmod 2=1] \\ &=\sum_{j=0}^{30}\sum_{i=0}^{\lfloor \frac{n-r}{m}\rfloor} [\lfloor\frac{im+r}{2^j}\rfloor-2\times \lfloor \frac{\lfloor\frac{im+r}{2^j}\rfloor}{2}\rfloor=1] \\ &= \sum_{j=0}^{30}\sum_{i=0}^{\lfloor \frac{n-r}{m}\rfloor} \lfloor\frac{im+r}{2^j}\rfloor-2\times \lfloor {\frac{im+r}{2^{j+1}}}\rfloor \end{aligned}

对比原来的 f 函数:

f(a,b,c,n)=\sum_{i=0}^n\lfloor \frac{ai+b}{c}\rfloor

显然直接转化。

【SX/NOI-】P5171

upd 2025/05/21.

求的是 ax+by\leq c非负整数解

学过初中数学的就可以知道:

\begin{aligned} ax+by & \leq c \\ by & \leq c-ax\\ y & \leq \frac{c-ax}{b} \end{aligned}

由于是非负整数解,所以:

y\leq\lfloor \frac{c-ax}{b} \rfloor

那么对于 y\lfloor \frac{c-ax}{b} \rfloor+1非负整数解。

考虑枚举 x,注意:

\begin{aligned} c-ax&\ge 0\\ ax&\le c\\ x&\le \frac{c}{a} \end{aligned}

我们可以确定枚举上界为 \lfloor \frac{c}{a} \rfloor

答案就是

\sum_{x=0}^{\lfloor \frac{c}{a} \rfloor}\lfloor \frac{c-ax}{b} \rfloor+1

但这 x 的系数怎么是 -a??

我们需要变形:

\begin{aligned} \sum_{x=0}^{\lfloor \frac{c}{a} \rfloor}\lfloor \frac{c-ax}{b} \rfloor+1 &=\sum_{x=0}^{\lfloor \frac{c}{a} \rfloor}\lfloor \frac{c+(b-a)x}{b} \rfloor-x+1 \\ &=\sum_{x=0}^{\lfloor \frac{c}{a} \rfloor}\lfloor \frac{c+(b-a)x}{b} \rfloor-\sum_{x=0}^{\lfloor \frac{c}{a} \rfloor}x+\sum_{x=0}^{\lfloor \frac{c}{a} \rfloor}1 \\ &=\lfloor \frac{c}{a} \rfloor+ (\sum_{x=0}^{\lfloor \frac{c}{a} \rfloor}\lfloor \frac{c+(b-a)x}{b} \rfloor)-\sum_{x=0}^{\lfloor \frac{c}{a} \rfloor}x\\ &=\lfloor \frac{c}{a} \rfloor+ (\sum_{x=0}^{\lfloor \frac{c}{a} \rfloor}\lfloor \frac{c+(b-a)x}{b} \rfloor)-\frac{\lfloor \frac{c}{a} \rfloor(\lfloor \frac{c}{a} \rfloor+1)}{2} \end{aligned}

你学会了吗?

【SX/NOI-】ABC408G & P5179

upd 2025/06/04.

类欧思想练手题。(纪第一次切 G)

考虑一个同样类似欧几里得的做法。(主要是思想,不是函数相同)

下文同步载于 G 题题解区

是这么一个东西,原式满足不等式:

\frac{a}{b}<\frac{p}{q}<\frac{c}{d}

取倒数:

\frac{d}{c}<\frac{q}{p}<\frac{b}{a}

分离常数,设 v=\lfloor \frac{d}{c} \rfloor

\frac{d-cv}{c}<\frac{q-vp}{p}<\frac{b-va}{a}

其实就是:

\frac{d\bmod c}{c}<\frac{q-vp}{p}<\frac{b-va}{a}

递归,我们发现:

$$ \frac{a}{b}<1<\frac{c}{d} $$ 那么取 $p=1,q=1$。 本质就是递归到这个状态。 然后我们可以考虑逆推,每一次都有调换。 最后输出答案 $q$ 即可。 ```cpp #include<bits/stdc++.h> using namespace std; #define int long long int T; void gcd(int a,int b,int &p,int &q,int c,int d){ if(a<b&&c>d) p=1,q=1; else{ gcd(d%c,c,q,p,b-(d/c)*a,a); q+=(d/c)*p; } } signed main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>T; while(T--){ int a,b,c,d; cin>>a>>b>>c>>d; int p,q; gcd(a,b,p,q,c,d); cout<<q<<"\n"; } } ``` 代码跟上面一样,我就不过多赘述了。 但是求答案有必要讲一下,为什么要加回来呢? 我们倒推时其实不知道 $p$,$q$ 的值,只有倒推回来时才知道上一步的值,所以要加回 $vp$,才是原本 $q$ 的值。 综上,此题难度是小学数学题。