题目描述
给定 \(A,B,C\),求满足方程 \(Ax+By\leq C\) 的 非负 整数解 \((x,y)\)(\(A,B\leq 10^9,C\leq \min(A,B)\times 10^9\))。
分析
考虑枚举 \(y\),移项得:\(0\leq y\leq \lfloor\frac{C-Ax}{B}\rfloor\),当 $ x=0$ 时,\(y\) 枚举的上界为 \(\lfloor\frac{C}{A}\rfloor\)。
这相当于求线段 \(y=\frac{C-Ax}{B}(0\leq y\leq \lfloor\frac{C}{A}\rfloor)\) 在第一象限和 \(x,y\) 正半轴内整点的数量。
把斜率为负调整成斜率为正的线段,原来线段的两端点为 \((0,\frac{C}{B}),(\lfloor\frac{C}{A}\rfloor,\frac{C-A\lfloor\frac{C}{A}\rfloor}{B})\),将两端点对换,分别为 \((0,\frac{C-A\lfloor\frac{C}{A}\rfloor}{B}),(\lfloor\frac{C}{A}\rfloor,\frac{C}{B})\),此时线段为 \(y=\frac{A}{B}x+\frac{C-A\lfloor\frac{C}{A}\rfloor}{B}=\frac{Ax+C\% A}{B}\)。
问题即求(加 \(1\) 是因为 \(x=0\) 时也是合法解):
\[\sum_{i=0}^{\lfloor\frac{C}{A}\rfloor}\Big(\Big\lfloor\frac{Ax+C\%A}{B}\Big\rfloor+1\Big)=\sum_{x=0}^{\lfloor\frac{C}{A}\rfloor}\Big(\Big\lfloor\frac{Ax+C\%A+B}{B}\Big\rfloor\Big) \]考虑一个一般性问题:
\[f(a,b,c,n)=\sum_{i=0}^{n}\Big\lfloor\frac{ai+b}{c}\Big\rfloor \]\(1.\) 当 \(a\geq c\) 或 \(b\geq c\) 时,
\(2.\) 当 \(a<c\) 且 \(b<c\) 时,
可以发现右边递归成为子问题,继续一轮操作即可。边界条件:\(a=0\)。
代码
#include<bits/stdc++.h>
using namespace std;
long long A,B,C;
long long solve(long long a,long long b,long long c,long long n)
{
if(a==0)
return (n+1)*(b/c);
if(a>=c||b>=c)
return solve(a%c,b%c,c,n)+(a/c)*n*(n+1)/2+(b/c)*(n+1);
long long m=(a*n+b)/c;
return n*m-solve(c,c-b-1,a,m-1);
}
int main()
{
cin>>A>>B>>C;
cout<<solve(A,C%A+B,B,C/A)<<endl;
return 0;
}