[BZOJ2987]Earthquake:類歐幾里得演算法
阿新 • • 發佈:2019-01-11
分析
類歐的式子到底是誰推的啊怎麼這麼神仙啊orz!
簡單說一下這道題,題目中的約束條件可以轉化為:
\[ y \leq \frac{c-ax}{b} \]
有負數怎麼辦啊?轉化一下:
\[ y \leq \frac{ax+c\%a}{b} \]
唔姆,好像差不多。
列舉\(x\),可以看成那個類歐的式子(\(\sum_{i=0}^{n} \lfloor \frac{ai+b}{c} \rfloor\))。
然後就能上類歐搞了,注意邊界條件是\(c=0\)時返回\(0\)。
程式碼
#include <bits/stdc++.h> #define rin(i,a,b) for(register int i=(a);i<=(b);++i) #define irin(i,a,b) for(register int i=(a);i>=(b);--i) #define trav(i,a) for(register int i=head[a];i;i=e[i].nxt) typedef long long LL; using std::cin; using std::cout; using std::endl; inline LL read(){ LL x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();} return x*f; } LL a,b,c; LL gcd(LL n,LL a,LL b,LL c){ if(!c) return 0; if(a>=c||b>=c) return n*(n+1)/2*(a/c)+(n+1)*(b/c)+gcd(n,a%c,b%c,c); else return n*((a*n+b)/c)-gcd((a*n+b)/c-1,c,c-b-1,a); } int main(){ a=read(),b=read(),c=read(); printf("%lld\n",gcd(c/a,a,c%a,b)+c/a+1); return 0; }