[CF1182F]Maximum Sine


題意:\(f(x) = \text{abs}(\text{sin}(\frac{p}{q} \pi x))\),給定$a,b,p,q$,求$x\in[a,b]$最大的$f(x)$。

題解:div2都這么仙了嗎。。。

根據高中數學知識可以推出要求的就是使得$\frac{px \mod q}\(最接近\)\frac12$的$x$,也就是$px \mod q$最接近$\frac q2$。

有一個結論:\([px \mod q \in [l,r]] = \lfloor\frac{px-l}{q}\rfloor - \lfloor\frac{px-r-1}{q}\rfloor\)。考慮二分$px \mod q$與$\frac q2$的距離,對於一個$mid$,相當於要求是否存在$x$使得$px \mod q \in [l=\frac q2-mid,r=\frac q2+mid]\(。根據上述結論,這等價於\)\sum_^b\lfloor\frac\rfloor - \lfloor\frac\rfloor$是否$>0$。這個式子是可以類歐求的。

求出最小距離以后,用$\text$還原$x$即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll Inf = 1e18;

int gi() {
  int x = 0, o = 1;
  char ch = getchar();
  while((ch < '0' || ch > '9') && ch != '-') {
    ch = getchar();
  }
  if(ch == '-') {
    o = -1, ch = getchar();
  }
  while(ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0', ch = getchar();
  }
  return x * o;
}

ll solve(ll n, ll a, ll b, ll c) {
  if(n < 0) {
    return 0;
  }
  if(!n) {
    return b / c;
  }
  if(a >= c || b >= c) {
    return solve(n, a % c, b % c, c) + n * (n + 1) / 2 * (a / c) + (n + 1) * (b / c);
  }
  ll m = (a * n + b) / c;
  return m * n - solve(m - 1, c, c - b - 1, a);
}

ll solve(ll l, ll r, ll a, ll b, ll c) {
  return solve(r, a, b, c) - solve(l - 1, a, b, c);
}

void exgcd(ll a, ll b, ll &x, ll &y) {
  if(!b) {
    x = 1, y = 0;
    return;
  }
  exgcd(b, a % b, y, x), y -= a / b * x;
}

ll a, b, p, q;

ll solve(ll p, ll q, ll t) {
  ll gg = __gcd(p, q);
  if(t % gg != 0) {
    return Inf;
  }
  p /= gg, q /= gg, t /= gg;
  ll x, y;
  exgcd(p, q, x, y);
  x *= t, y *= t;
  ll k = (a - x) / q;
  x += k * q;
  while(x >= a) {
    x -= q;
  }
  while(x < a) {
    x += q;
  }
  return x;
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("a.in", "r", stdin);
  freopen("a.out", "w", stdout);
#endif
  int T = gi();
  while(T--) {
    a = gi(), b = gi(), p = gi() << 1, q = gi() << 1;
    ll l = 0, w = q / 2, r = w;
    while(l < r) {
      ll mid = (l + r) >> 1;
      ll L = w - mid, R = w + mid;
      if(solve(a, b, p, q - L, q) - solve(a, b, p, q - R - 1, q)) {
        r = mid;
      } else {
        l = mid + 1;
      }
    }
    cout << min(solve(p, q, w - l), solve(p, q, w + l)) << endl;
  }
  return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM