【BZOJ2987】类欧几里得算法

写于2019.06.02 刚学习了类欧算法(除了时间复杂度,和欧算一点关系都没有orz),还没来得及肝先知和圣骑士。

2987: Earthquake

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 283 Solved: 161
[Submit][Status][Discuss]

Description

给定a,b,c,求满足方程Ax+By<=C的非负整数解

A,B<=109.C<=Min(A,B)*109

Input

Output

Sample Input

3 4 13

Sample Output

12

移项得到

\[ y \le \frac{c-a*x}{b} \]

啥,有负数形式,显然不棒
那么我们转换一下变成了 y \le \frac{a*x+c%b}{b}
x可以从0枚举到c/a,这样就很像类欧里面的形式

\[\sum_{i=0}^n \lfloor \frac{a*i+b}{c} \rfloor \]

直接套用就可以了,具体可以见luogu模板题题解

#include<bits/stdc++.h>
typedef long long ll;

using namespace std;


ll a,b,c;

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

int main() {
	scanf("%lld%lld%lld",&a,&b,&c);
	printf("%lld\n",F(a,c%a,b,c/a)+c/a+1);
}
posted @ 2021-09-04 20:57  Newuser233  阅读(35)  评论(0编辑  收藏  举报