传送门
题意简述:求满足
a
x
+
b
y
+
c
≤
0
ax+by+c\le0
ax+by+c≤0的二元组
(
x
,
y
)
(x,y)
(x,y)对数。
思路:
类欧几里得算法模板题。
把式子变化一下变成:求满足
0
≤
y
≤
−
a
x
+
c
b
0\le y\le\frac{-ax+c}b
0≤y≤b−ax+c的二元组
(
x
,
y
)
(x,y)
(x,y)对数。
然后就变成求
∑
i
=
0
⌊
c
a
⌋
⌊
−
a
x
+
c
b
⌋
+
1
\sum_{i=0}^{\left\lfloor\frac ca\right\rfloor}\left\lfloor\frac{-ax+c}b\right\rfloor+1
∑i=0⌊ac⌋⌊b−ax+c⌋+1
直接上类欧几里得即可,注意处理负数的情况。
不会类欧几里得算法的点这里
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
ll a,b,c;
inline ll solve(ll a,ll b,ll c,ll n){
if(!n)return b/c;
if(n==1)return (a+b)/c+b/c;
if(c<0)return solve(-a,-b,-c,n);
if(a>=c||b>=c)return solve(a%c,b%c,c,n)+n*(n+1)/2*(a/c)+(n+1)*(b/c);
if(!a)return 0;
if(a<0||b<0)return solve(a%c+c,b%c+c,c,n)+n*(n+1)/2*(a/c-1)+(n+1)*(b/c-1);
ll m=(a*n+b)/c;
return n*m-solve(c,-b+c-1,a,m-1);
}
int main(){
cin>>a>>b>>c;
cout<<c/a+1+solve(-a,c,b,c/a);
return 0;
}