DestinHistoire

 

BZOJ-2987 Earthquake(类欧几里得算法)

题目描述

  给定 \(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;
}

posted on 2020-12-01 18:51  DestinHistoire  阅读(44)  评论(0编辑  收藏  举报

导航