bzoj2987 Earthquake 类欧几里得

匿名 (未验证) 提交于 2019-12-03 00:32:02

Description


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

A,B<=10^9.C<=Min(A,B)*10^9

Solution


考虑枚举x得到yCAxB
类欧几里得的经典应用,时间太紧了我就先去吃个饭回来再写
回来辣
类欧的几何意义可以看成是求一个梯形内的整点数,不包括纵坐标为0的点,包括边界上的点
先设f(n,a,b,c)=i=0nai+bc
acbc,那么有
f(n,a,b,c)=(n+1)n2ac+(n+1)bc+f(n,a%c,b%c,c)
至于怎么推的可以考虑把前面两项再塞回∑里面看看

若两个都不满足,那么令m=na+bc,有
f(n,a,b,c)=i=0nj=1m[jai+bc],这个可以看成是枚举可行的整点
我们把表达式单独拉出来jai+bc
化一下把i单独弄出来得到icj+cb1a,套进原本的柿子里面,这个就等同于一行一行枚举了
然后有f(n,a,b,c)=nmf(m1,c,cb1,a)

复杂度分析到处都有我就不贴了

Code


#include <stdio.h> #include <string.h> #define rep(i,st,ed) for (int i=st;i<=ed;++i)  typedef long long LL;  LL solve(LL n,LL a,LL b,LL c) {     if (!c) return 0;     if (a>=c||b>=c) {         return solve(n,a%c,b%c,c)+(a/c)*n*(n+1)/2+(b/c)*(n+1);     } else {         LL m=(n*a+b)/c;         return n*m-solve(m-1,c,c-b-1,a);     } }  int main(void) {     LL a,b,c; scanf("%lld%lld%lld",&a,&b,&c);     printf("%lld\n", solve(c/a,a,c%a,b)+c/a+1);     return 0; }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!