类欧几里得
类欧几里得
基本是利用欧几里得的思想,来不断缩小问题规模。所以举栗子来推推式子。
一、BZOJ3817
求$Ans=\sum_{d=1}^{n}$$\lfloor (b*x+c)/a\rfloor*d,x=\sqrt r$
设$t=\lfloor (b*x+c)/a \rfloor$,$k=(b*x+c)/a-t$,显然$t>=1,k<1$
于是$Ans= \sum_{d=1}^n t*d+k*d$
通过画图,发现可以把枚举横坐标,变成枚举纵坐标。
$Ans=\frac{t*n*(n+1)}{2}+\sum_{d=1}^{kn} n-\lfloor d/k\rfloor$ ps:这里没有考虑直线经过整点
由上面的图得知当x为有理数时,即斜率会经过整点,而上公式会多减去。为了省事,就特判解决吧。或者偏移一下eps,奇数次计算包含整点,偶数次就不计算...
$\frac{1}{k}=\frac{a}{bx+c}$约分得$\frac{a*b*x-a*c}{b^2*r-c^2} $
贴一个核心代码 复杂度$O(\log n)$
ll solve(int n,int a,int b,int c) { if(n<=0){eps=fabs(eps);return 0;} int tmp=gcd(a,gcd(b,c));a/=tmp,b/=tmp,c/=tmp;//约分以防爆long long int t=(b*x+c)/a+eps; ll sum=(ll)n*(n+1)/2; c-=t*a;int k=((b*x+c)/a+eps)*n; eps=-eps; return t*sum+(ll)k*n-solve(k,b*b*r-c*c,a*b,-a*c); }
二、BZOJ2987
求$Ans=\sum_{x=1}^{n}\lfloor\frac{C+Bx}{A}\rfloor$
下面要求 $C<A \ \ \&\ B< A,A,B,C≥0$ 如果不满足可以通过这些来转换:
- $if\ \ B\lt0 \ \ t= \lfloor \frac{A-1-B}{A}\rfloor, Ans-=\frac{t*n*(n+1)}{2},B+=t*A$
- $if \ \ C\lt 0 \ \ t=\lfloor \frac{A-1-C}{A}\rfloor,Ans-=n*t,C+=A*t$ ps:$t为C变为\lt A的累加次数$
- $if \ \ C\ge A \ \ Ans+=\lfloor \frac{C}{A}\rfloor*n, C \%=A$
- $if \ \ B\ge A \ \ Ans +=\lfloor \frac{B}{A} \rfloor*\frac{n*(n+1)}{2},B\%=A $
然后来推式子:
$\begin{align} Ans & =\sum_{x=1}^{n}\lfloor\frac{C+Bx}{A}\rfloor \\& =\sum_{x=1}^{n} \sum_k[kA≤C+Bx] \\&= \sum_{k=1}^{\lfloor\frac{C+Bn}{A}\rfloor} n-\lfloor\frac{Ak-C}{B}\rfloor +1 \\& =\sum_{k=1}^{\lfloor\frac{C+Bn}{A}\rfloor} n-\lfloor\frac{Ak-C+B-1}{B}\rfloor +1 ps:Ak-C\le Bx\end{align} $
那么$n=\lfloor\frac{C+Bn}{A}\rfloor,B'=A,C=B-C-1,A'=B$
于是问题规模被不断缩小,复杂度$O(\log n)$
核心代码
ll solve(ll n,ll a,ll b,ll c) { if(n<=0)return 0; ll res=0; if(c<0) { ll t=(a-1-c)/a; res-=t*n;c+=a*t; } if(b<0) { ll t=(a-1-b)/a; res-=t*n*(n+1)>>1; b+=a*t; } if(c/a>0||b/a>0) { res+=(c/a)*n;res+=(b/a)*n*(n+1)>>1; c%=a;b%=a; } ll newn=(c+b*n)/a; res+=newn*(n+1)-solve(newn,b,a,b-c-1); return res; }
三、BZOJ2187,2712
求满足$\frac{a}{b}\lt\frac{p}{q}\lt\frac{c}{d}$的最小(q,p)
YY了一个想法:
$对于一个合法的q满足\lfloor \frac{a*q}{b}\rfloor+1\le\lfloor\frac{c*q-1}{d}\rfloor,$
$统计一个\sum_{i=1}^{q}\lfloor\frac{c*i-1}{d}\rfloor-\lfloor \frac{a*i}{b}\rfloor >0即存在q满足条件$
二分一下就好了....
然后来个正经的:
$if \ \ a=0 ==>p=1,q=\lfloor\frac{d}{c}\rfloor+1$
$else \ \ if \ \ a<=b\&\&c<=d ==> \frac{d}{b}\lt\frac{p}{q}\lt\frac{c}{a} $
$else \ \ \frac{a\%b}{b}\lt\frac{p-\lfloor\frac{a}{b}\rfloor*q}{q}-\lt\frac{c-\lfloor\frac{a}{b}\rfloor*b}{d}$
于是又变成了不断递归的过程...
一颗赛艇.......
核心代码
void simplify(ll &a,ll &b)
{
ll x=gcd(a,b);a/=x;b/=x;
}
void solve(ll a,ll b,ll &p,ll &q,ll c,ll d) { simplify(a,b); simplify(c,d); if(a==0) { p=1;q=d/c+1;return; }else if(a/b+1<ceil((double)c/d)) { q=1;p=a/b+1;return; }else if(a<=b&&c<=d){solve(d,c,q,p,b,a);return;} ll t=a/b; solve(a%b,b,p,q,c-t*d,d); p+=q*t; }
[未完待续....]