zoukankan      html  css  js  c++  java
  • CF1182F Maximum Sine

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

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

    [large [2px mod 2q in[l,r]]=leftlfloor frac{2px-l}{2q} ight floor-leftlfloor frac{2px-r-1}{2q} ight floor ]

    因此,得:

    [large exist x in [a,b],2px mod 2q in[l,r] Leftrightarrow sum_{x=a}^b left( leftlfloor frac{2px-l}{2q} ight floor-leftlfloor frac{2px-r-1}{2q} ight floor ight)>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
    ",min(calc(p,q,a,b,q/2-ans),calc(p,q,a,b,q/2+ans)));
        }
        return 0;
    }
    
  • 相关阅读:
    Oracle函数题
    多态
    继承
    封装
    属性和修饰符
    方法重载
    构造方法
    类与实例
    SQL Server 2005 To Oracle
    Toad for Oracle 使用文档
  • 原文地址:https://www.cnblogs.com/lhm-/p/13843467.html
Copyright © 2011-2022 走看看