[P5170] 类欧几里得算法

のすたの“类欧几里得算法”第二题 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;
}

原文地址:https://www.cnblogs.com/nosta/p/10301242.html

时间: 2024-08-14 06:31:27

[P5170] 类欧几里得算法的相关文章

bzoj3817 Sum 类欧几里得算法

这道题目solution写了两种做法,都讲一下吧. 首先,令x=r^0.5,显然,如果x>2,则可以不断减2到小于二:如果x>1,那么变为2-x.因此此时必有x<1.(特判r为完全平方数的情况).那么令y=1/x,则: 题目等价于在数轴从0~n,以y长度为一个区间(左闭右开)黑白交替染色,求黑色部分覆盖的整点减去白色部分覆盖的整点.然后把最后面零散的部分暴力计算,如果最后一个是黑色的也暴力计算.那么这个时候黑白段数相等,且每一段黑(白)都至少覆盖[y]个点恰好各自抵消[y],那么将每一段

BZOJ3817 Sum(类欧几里得算法)

设$t=\sqrt r$,原题转化为$\sum_{x=1}^n(4*\lfloor\frac{tx}2\rfloor-2*\lfloor tx\rfloor)$考虑如何求$\sum_{x=1}^n\lfloor\frac{bt+c}ax\rfloor$开始我写了一个真欧几里得来求直线下整点数目,然后由于里头含小数所以不对.于是学习了一下新姿势,思想其实差不多.先把a,b,c同时除以gcd(a,b,c),防止爆int.之后把斜率变成$\frac{bt+c}a-\lfloor\frac{bt+c}a

类欧几里得算法浅谈(部分)

学习类欧几里得算法,因为是蒟蒻,感觉网上很多都看不懂,所以自己写一篇快活快活 第一类求和式: \(F(a,b,c,n)=\sum_{i=0}^n\lfloor\frac{a*i+b}{c}\rfloor\) 对于这样形式的求和,我们有以下的推导: 1.当\(a>=c\)并且\(b>=c\)时,我们有: 对于\(\lfloor\frac{a}{c}\rfloor\), 它实际等价于\(\lfloor\frac{a\mod c}{c}\rfloor+\lfloor\frac{a}{c}\rfloo

类欧几里得算法

对于求和式 $f(a,b,c,n)=\sum_{i=0}^n \lfloor \frac{ai+b}{c} \rfloor$ 当 $a \geq c$ 或 $b \geq c$ 时,设 $a'=a \; mod \; c$,$b'=b \; mod \; c$,有 $$\begin{align*} f(a,b,c,n) = & \sum_{i=0}^n \; \lfloor \frac{ai+b}{c} \rfloor \\ = & \sum_{i=0}^n \; \lfloor \fra

数论,类欧几里得算法

类欧几里得部分转载自不来也不去的一只失忆蝴蝶.%%%

[补档计划] 类欧几里得算法

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

模板 - 类欧几里得算法

用来快速求解 $\sum\limits_{i=0}^{n}\lfloor \frac{ai+b}{c} \rfloor,\sum\limits_{i=0}^{n}{\lfloor \frac{ai+b}{c} \rfloor}^2,\sum\limits_{i=0}^{n}i\lfloor \frac{ai+b}{c} \rfloor $ 有多快呢?据说是log的?反正abc取1e9可以200ms过1e5组询问-- #include <bits/stdc++.h> typedef long l

【LuoguP4433】[COCI2009-2010#1] ALADIN(含类欧几里得算法推导)

题目链接 题意简述 区间赋值模意义下等差数列,询问区间和 \(N\leq 10^9,Q\leq 10^5\) Sol 每次操作就是把操作区间\([L,R]\)中的数赋值成: \[(X-L+1)*A\ mod\ B\] 考虑用线段树维护. 我们只需要能快速知道一段区间\([l,r]\)被覆盖后的和就行了,因为覆盖的标记易于下传: \[\sum_{i=l}^{r} (i-L+1)*A\ mod\ B\] 根据基础的数学知识,mod显然不好算,把它拆开: \[\sum_{i=l}^r (i-L+1)*

欧几里得算法求最大公约数+最小公倍数

1,两个数互质:如果说两个数的公因数只有1,则可以说这两个数互质. 欧几里得算法求最大公约数: 首先求最大公约数,假设我们要求a和b的最大公约数 设a mod b = c: 可以得到一下的递推过程: a = kb + c ; 假设a , b 的最大公约数为d,则可以得到: a = md , b = nd; 可知m , n 互质: c = a - kb = md - knd = (m-kn)d; 我们已经知道m,n互质,则可以知道n和m-kn互质,则c和b的最大公约数也是d; 所以由以上的推论,我