CF1182F Maximum Sine

最大化 \(f(x)=\left|\sin\left(\frac{p}{q}\pi x\right)\right|\) 就是让 \(\frac{px}{q}\) 越接近 \(\frac{1}{2}+k\),即 \(\frac{px}{q}\) 的小数部分 \(\frac{px \bmod q}{q}\) 越接近 \(\frac{1}{2}\)

转化后为使 \(|2px \bmod 2q -q|\) 最小,二分该值 \(v\),设 \(l=q-v,r=q+v\),得判定 \(2px \bmod 2q\) 是否在区间 \([l,r]\) 内,有个结论:

\[\large [2px \bmod 2q \in[l,r]]=\left\lfloor \frac{2px-l}{2q} \right\rfloor-\left\lfloor \frac{2px-r-1}{2q} \right\rfloor \]

因此,得:

\[\large \exist x \in [a,b],2px \bmod 2q \in[l,r] \Leftrightarrow \sum_{x=a}^b \left( \left\lfloor \frac{2px-l}{2q} \right\rfloor-\left\lfloor \frac{2px-r-1}{2q} \right\rfloor \right)>0 \]

和式用类欧计算,二分后用扩欧解同余方程即可求出 \(x\)

#include<bits/stdc++.h>
#define inf 1000000000000000000
using namespace std;
typedef long long ll;
template<typename T> inline void read(T &x)
{
    x=0;char c=getchar();bool flag=false;
    while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    if(flag)x=-x;
}
int T;
ll a,b,p,q,l,r,ans;
ll f(ll n,ll a,ll b,ll c)
{
    if(n<0) return 0;
    if(!a) return (n+1)*(b/c);
    if(a>=c||b>=c) return (n+1)*n/2*(a/c)+(n+1)*(b/c)+f(n,a%c,b%c,c);
    ll m=(n*a+b)/c;
    return n*m-f(m-1,c,c-b-1,a);
}
bool check(ll v)
{
    ll l=q/2-v,r=q/2+v,v1,v2;
    return f(b,p,q-l,q)-f(a-1,p,q-l,q)-f(b,p,q-r-1,q)+f(a-1,p,q-r-1,q);
}
ll gcd(ll a,ll b)
{
    return b?gcd(b,a%b):a;
}
void exgcd(ll a,ll b,ll &x,ll &y)
{
    if(!b) x=1,y=0;
    else exgcd(b,a%b,y,x),y-=a/b*x;
}
ll calc(ll p,ll q,ll a,ll b,ll v)
{
    ll g=gcd(p,q),x,y;
    if(v%g) return inf;
    p/=g,q/=g,exgcd(p,q,x,y);
    x*=v/g,x+=(a-x)/q*q;
    while(x<a) x+=q;
    while(x-q>=a) x-=q;
    if(x>b) return inf;
}
int main()
{
    read(T);
    while(T--)
    {
        read(a),read(b),read(p),read(q),l=ans=0,r=q,p*=2,q*=2;
        while(l<=r)
        {
            ll mid=(l+r)>>1;
            if(check(mid)) ans=mid,r=mid-1;
            else l=mid+1;
        }
        printf("%lld\n",min(calc(p,q,a,b,q/2-ans),calc(p,q,a,b,q/2+ans)));
    }
    return 0;
}
posted @ 2020-10-19 22:10  lhm_liu  阅读(204)  评论(0编辑  收藏  举报