类欧几里得学习

类欧几里得算法学习

模型

类欧几里得是用来快速的求以下式子:

  • f ( a , b , c , n ) = ∑ i = 0 n [ a i + b c ] f(a,b,c,n)=\sum_{i=0}^n [\frac{ai+b}{c}] f(a,b,c,n)=i=0n[cai+b]
  • g ( a , b , c , n ) = ∑ i = 0 n i × [ a i + b c ] g(a,b,c,n)=\sum_{i=0}^n i\times[\frac{ai+b}{c}] g(a,b,c,n)=i=0ni×[cai+b]
  • h ( a , b , c , n ) = ∑ i = 0 n [ a i + b c ] 2 h(a,b,c,n)=\sum_{i=0}^n [\frac{ai+b}{c}]^2 h(a,b,c,n)=i=0n[cai+b]2

因其求解的方式与欧几里得算法类似,故被称为类欧几里得算法,同样时间复杂度为O(logn)。

计算 f(a,b,c,n)

当a>=c||b>=c

  • ∑ i = 0 n [ a i + b c ] = ∑ i = 0 n [ a % c × i + b % c c ] + [ a c ] ∑ i + [ b c ] ∑ \sum_{i=0}^n [\frac{ai+b}{c}]=\sum_{i=0}^n [\frac{a\%c\times i+b\%c}{c}]+[\frac{a}{c}]\sum i+[\frac{b}{c}]\sum i=0n[cai+b]=i=0n[ca%c×i+b%c]+[ca]i+[cb]
  • f ( a , b , c , n ) = f ( a % c , b % c , c , n ) + [ a c ] ( n × ( n + 1 ) / 2 ) + [ b c ] × ( n + 1 ) f(a,b,c,n)=f(a\%c,b\%c,c,n)+[\frac{a}{c}](n\times (n+1)/2)+[\frac{b}{c}]\times (n+1) f(a,b,c,n)=f(a%c,b%c,c,n)+[ca](n×(n+1)/2)+[cb]×(n+1)

当a<c&&b<c

  • 对于 ∑ i = 0 n [ a i + b c ] \sum_{i=0}^n [\frac{ai+b}{c}] i=0n[cai+b],其还有一个几何意思是:求一条直线下方的整点数量。
  • m = ⌊ a n + b c ⌋ − 1 m=\lfloor \frac{an+b}{c}\rfloor-1 m=can+b1
  • f ( a , b , c , n ) f(a,b,c,n) f(a,b,c,n)
    = ∑ i = 0 n [ a i + b c ] =\sum_{i=0}^n [\frac{ai+b}{c}] =i=0n[cai+b]
    = ∑ i = 0 n ∑ j = 1 m + 1 [ j < = ⌊ a i + b c ⌋ ] =\sum_{i=0}^n\sum_{j=1}^{m+1}[j<=\lfloor \frac{ai+b}{c}\rfloor] =i=0nj=1m+1[j<=cai+b]
    = ∑ j = 1 m + 1 ∑ i = 0 n [ j < = ⌊ a i + b c ⌋ ] =\sum_{j=1}^{m+1}\sum_{i=0}^{n}[j<=\lfloor \frac{ai+b}{c}\rfloor] =j=1m+1i=0n[j<=cai+b]
    = ∑ j = 0 m ∑ i = 0 n [ j + 1 < = ⌊ a i + b c ⌋ ] =\sum_{j=0}^{m}\sum_{i=0}^{n}[j+1<=\lfloor \frac{ai+b}{c}\rfloor] =j=0mi=0n[j+1<=cai+b]
    = ∑ j = 0 m ∑ i = 0 n [ j + 1 < = a i + b c ] =\sum_{j=0}^{m}\sum_{i=0}^{n}[j+1<=\frac{ai+b}{c}] =j=0mi=0n[j+1<=cai+b]
    = ∑ j = 0 m ∑ i = 0 n [ j c + c < = a i + b ] =\sum_{j=0}^{m}\sum_{i=0}^{n}[jc+c<=ai+b] =j=0mi=0n[jc+c<=ai+b]
    = ∑ j = 0 m ∑ i = 0 n [ a i > j c + c − b − 1 ] =\sum_{j=0}^{m}\sum_{i=0}^{n}[ai>jc+c-b-1] =j=0mi=0n[ai>jc+cb1]
    = ∑ j = 0 m ∑ i = 0 n [ i > j c + c − b − 1 a ] =\sum_{j=0}^{m}\sum_{i=0}^{n}[i>\frac{jc+c-b-1}{a}] =j=0mi=0n[i>ajc+cb1]
    = ∑ j = 0 m ( n − ⌊ j c + c − b − 1 a ⌋ ) =\sum_{j=0}^m(n-\lfloor\frac{jc+c-b-1}{a}\rfloor) =j=0m(najc+cb1)
    = ∑ i = 0 m n − f ( c , c − b − 1 , a , m ) =\sum_{i=0}^mn-f(c,c-b-1,a,m) =i=0mnf(c,cb1,a,m)

当n=0 f ( a , b , c , n ) = [ b c ] f(a,b,c,n)=[\frac{b}{c}] f(a,b,c,n)=[cb]
当a=0 f ( a , b , c , n ) = ( n + 1 ) [ b c ] f(a,b,c,n)=(n+1) [\frac{b}{c}] f(a,b,c,n)=(n+1)[cb]

代码如下:

ll f(ll a,ll b,ll c,ll n){
	if(n==0)return b/c;
	if(a==0)return b/c*(n+1);
	if(a>=c&&b>=c)return f(a%c,b%c,c,n)+a/c*(n*n+1)/2+b/c*(n+1);
    if(a<c||b<c)return (a*n+b)/c*n+f(c,c-b-1,a,(an+b)/c-1);
}

计算h(a,b,c,n)

当a>=c||b>=c

  • h ( a , b , c , n ) = ∑ i = 0 n [ a i + b c ] 2 h(a,b,c,n)=\sum_{i=0}^n[\frac{ai+b}{c}]^2 h(a,b,c,n)=i=0n[cai+b]2
  • = ∑ i = 0 n ( [ a c ] × i + [ b c ] + [ a % c × i + b % c c ] ) 2 =\sum_{i=0}^n([\frac{a}{c}]\times i+[\frac{b}{c}]+[\frac{a\%c\times i+b\%c}{c}])^2 =i=0n([ca]×i+[cb]+[ca%c×i+b%c])2
  • 根据三个的完全平方数展开得到
  • 原式 = ∑ i = 0 n ( [ a c ] × i ) 2 + ∑ i = 0 n ( [ b c ] ) 2 + ∑ i = 0 n ( [ a % c × i + b % c c ] ) 2 + 2 [ a c ] [ b c ] ∑ i = 0 n i + 2 [ a c ] ∑ i = 0 n i [ a % c × i + b % c c ] + 2 [ b c ] ∑ i = 0 n [ a % c × i + b % c c ] =\sum_{i=0}^n([\frac{a}{c}]\times i)^2+\sum_{i=0}^n([\frac{b}{c}])^2+\sum_{i=0}^n([\frac{a\%c\times i+b\%c}{c}])^2+2[\frac{a}{c}][\frac{b}{c}]\sum_{i=0}^ni+2[\frac{a}{c}]\sum_{i=0}^ni[\frac{a\%c\times i+b\%c}{c}]+2[\frac{b}{c}]\sum_{i=0}^n[\frac{a\%c\times i+b\%c}{c}] =i=0n([ca]×i)2+i=0n([cb])2+i=0n([ca%c×i+b%c])2+2[ca][cb]i=0ni+2[ca]i=0ni[ca%c×i+b%c]+2[cb]i=0n[ca%c×i+b%c]
  • 化简得到 = [ a c ] 2 × ( n ( n + 1 ) ( 2 n + 1 ) ) 6 + [ b c ] 2 × ( n + 1 ) + h ( a % c , b % c , c , n ) + 2 [ a c ] [ b c ] × n ( n + 1 ) 2 + 2 [ a c ] g ( a % c , b % c , c , n ) + 2 [ b c ] f ( a % c , b % c , c , n ) =[\frac{a}{c}]^2\times \frac{(n(n+1)(2n+1))}{6}+[\frac{b}{c}]^2\times (n+1)+h(a\%c,b\%c,c,n)+2[\frac{a}{c}][\frac{b}{c}]\times \frac{n(n+1)}{2}+2[\frac{a}{c}]g(a\%c,b\%c,c,n)+2[\frac{b}{c}]f(a\%c,b\%c,c,n) =[ca]2×6(n(n+1)(2n+1))+[cb]2×(n+1)+h(a%c,b%c,c,n)+2[ca][cb]×2n(n+1)+2[ca]g(a%c,b%c,c,n)+2[cb]f(a%c,b%c,c,n)

当a<c&&b<c

  • 同理根据证明直接写出最后结论,设 m = [ a n + b c ] − 1 m=[\frac{an+b}{c}]-1 m=[can+b]1
  • h ( a , b , c , n ) = n ( m + 1 ) 2 − 2 g ( c , c − b − 1 , a , m ) − f ( c , c − b − 1 , a , m ) h(a,b,c,n)=n(m+1)^2-2g(c,c-b-1,a,m)-f(c,c-b-1,a,m) h(a,b,c,n)=n(m+1)22g(c,cb1,a,m)f(c,cb1,a,m)

当n=0 h ( a , b , c , n ) = [ b c ] 2 h(a,b,c,n)=[\frac{b}{c}]^2 h(a,b,c,n)=[cb]2
当a=0 h ( a , b , c , n ) = ( n + 1 ) × [ b c ] 2 h(a,b,c,n)=(n+1)\times [\frac{b}{c}]^2 h(a,b,c,n)=(n+1)×[cb]2

计算g(a,b,c,n)

当a>=c||b>=c

  • g ( a , b , c , n ) = ∑ i = 0 n i [ a i + b c ] g(a,b,c,n)=\sum_{i=0}^ni[\frac{ai+b}{c}] g(a,b,c,n)=i=0ni[cai+b]
  • = [ a c ] n ( n + 1 ) ( 2 n + 1 ) 6 + [ b c ] n ( n + 1 ) 2 + g ( a % c , b % c , c , n ) =[\frac{a}{c}]\frac{n(n+1)(2n+1)}{6}+[\frac{b}{c}]\frac{n(n+1)}{2}+g(a\%c,b\%c,c,n) =[ca]6n(n+1)(2n+1)+[cb]2n(n+1)+g(a%c,b%c,c,n)

当a<c&&b<c

  • m = [ a n + b c ] − 1 m=[\frac{an+b}{c}]-1 m=[can+b]1
  • g ( a , b , c , n ) = n ( n + 1 ) ( m + 1 ) − h ( c , c − b − 1 , a , m ) − f ( c , c − b − 1 , a . m ) 2 g(a,b,c,n)=\frac{n(n+1)(m+1)-h(c,c-b-1,a,m)-f(c,c-b-1,a.m)}{2} g(a,b,c,n)=2n(n+1)(m+1)h(c,cb1,a,m)f(c,cb1,a.m)

当n=0 f ( a , b , c , n ) = 0 f(a,b,c,n)=0 f(a,b,c,n)=0
当a=0 f ( a , b , c , n ) = [ b c ] ( n ( n + 1 ) 2 ) f(a,b,c,n)=[\frac{b}{c}](\frac{n(n+1)}{2}) f(a,b,c,n)=[cb](2n(n+1))

计算三者

由于后两者均需要其他形式,故递归的时候可以一起算比较快
模板如下:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll P = 998244353;
ll i2 = 499122177, i6 = 166374059;
struct data {
	ll f, g, h;
}; 
data calc(ll n, ll a, ll b, ll c) {
	ll ac = a / c, bc = b / c, m = (a * n + b) / c, n1 = n + 1, n21 = n * 2 + 1;
	data ans;
	ans.f=ans.g=ans.h=0;
	if (a == 0) {  // 迭代到最底层
		ans.f = bc * n1 % P;
		ans.g = bc * n % P * n1 % P * i2 % P;
		ans.h = bc * bc % P * n1 % P;
		return ans;
	}
	if (a >= c || b >= c) {  // 取模
		ans.f = n * n1 % P * i2 % P * ac % P + bc * n1 % P;
		ans.g = ac * n % P * n1 % P * n21 % P * i6 % P + bc * n % P * n1 % P * i2 % P;
		ans.h = ac * ac % P * n % P * n1 % P * n21 % P * i6 % P +
		      bc * bc % P * n1 % P + ac * bc % P * n % P * n1 % P;
		ans.f %= P, ans.g %= P, ans.h %= P;

		data e = calc(n, a % c, b % c, c);  // 迭代

		ans.h += e.h + 2 * bc % P * e.f % P + 2 * ac % P * e.g % P;
		ans.g += e.g, ans.f += e.f;
		ans.f %= P, ans.g %= P, ans.h %= P;
		return ans;
	} else {
		data e = calc(m - 1, c, c - b - 1, a);
		ans.f = n * m % P - e.f, ans.f = (ans.f % P + P) % P;
		ans.g = m * n % P * n1 % P - e.h - e.f, ans.g = (ans.g * i2 % P + P) % P;
		ans.h = n * m % P * (m + 1) % P - 2 * e.g - 2 * e.f - ans.f;
		ans.h = (ans.h % P + P) % P;
		return ans;
	}
}
ll T, n, a, b, c;
int main() {
	scanf("%lld", &T);
	while (T--) {
		scanf("%lld%lld%lld%lld", &n, &a, &b, &c);
		data ans = calc(n, a, b, c);
		printf("%lld %lld %lld\n", ans.f, ans.h, ans.g);
	}
	return 0;
}

例题

题目1:

  • 题目描述:求 ∑ i = 0 H M − 1 ∣ i / H M − i m o d M / ∣ < = A \sum_{i=0}^{HM-1} |i/HM-i modM/|<=A i=0HM1i/HMimodM/<=A
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值