此文更新于2019.6.13
    
            题意:
                f(x)=abs(sin((p/q)*PI*x)) a<=x<=b
                输入 p q a b
                输出f(x)取最大值时候的x
            数据范围:
                0<=a<=b<=1e9
                1<=p,q<=1e9
    
    
    
            最后等价于求[a,b]间的x使得(2px)%(2q) 和q最接近
            让x=m+kn , k=sqrt(b-a)
            枚举n二分m即可
    
    
    
    
            #include<bits/stdc++.h>
            using namespace std; 
            
            //
            //   | sin(px/qpi) |
            //
            //   (px/q)%1 -> 1/2
            //
            //   (2px)%(2q) -> q
            
            
            
            typedef long long ll; 
            const ll maxn=3e4+55; 
            struct node{
                ll x,gx; 
                bool operator<(const node&rhs) const {
                    if(gx!=rhs.gx) return gx<rhs.gx; 
                    else return x<gx; 
                }
            }g[maxn]; 
            
            ll get(ll p,ll q,ll x){
                return 2*p*x%(2*q); 
            }
            ll dis(ll p,ll q,ll x){
                return abs(get(p,q,x)-q); 
            }
            void update(ll&ans,ll cur,ll p,ll q){
                if(ans==-1) ans=cur; 
                else if(dis(p,q,cur)<dis(p,q,ans)) ans=cur; 
                else if(dis(p,q,cur)==dis(p,q,ans)) ans=min(ans,cur); 
            }
            int main(){
                ll n; 
                cin>>n; 
                while(n--){
                    ll a,b,p,q; 
                    cin>>a>>b>>p>>q; 
                    ll k=10000; 
                    map<int,int> mp; 
                    for(ll i=k-1;i>=0;i--) mp[get(p,q,i)]=i;//g[i]=node{i,get(p,q,i)};
                    ll sz=0; 
                    for(auto x:mp) g[sz++]=node{x.second,x.first}; 
            
                    ll bg=a,ans=-1; 
                    while(bg+k-1<=b){
                        ll base=get(p,q,bg), idx; 
                        if(base<=q) idx=lower_bound(g,g+sz,node{-1,q-base})-g; 
                        else idx=lower_bound(g,g+sz,node{-1,3*q-base})-g; 
            
                        update(ans,bg+g[idx%sz].x,p,q); 
                        update(ans,bg+g[(idx-1+sz)%sz].x,p,q); 
                        bg+=k; 
                    }
                    if(bg<=b){
                        for(ll i=bg;i<=b;i++) update(ans,i,p,q); 
                    }
                    cout<<ans<<endl; 
                }
            }
    
    
            此文标签
                 bsgs