類歐幾里得
基本是利用歐幾里得的思想,來不斷縮小問題規模。所以舉栗子來推推式子。
一、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; }
[未完待續....]
