## CF 1182F Maximum Sine——根号算法

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define mkp make_pair
#define fi first
#define se second
#define ll long long
using namespace std;
const int N=4e4+5,INF=1e9+5;
int a,b,p,q,p2,q2,bs,tot;
pair<ll,int> c[N],ans;
int main()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d",&a,&b,&p,&q);
p2=2*p; q2=2*q; bs=sqrt(b-a+1); tot=0;
for(int i=0;i<bs;i++)
c[++tot]=mkp((ll)p2*(a+i)%q2,i);
sort(c+1,c+tot+1);
//tot=unique(c+1,c+tot+1)-c-1;
tot=0;
for(int i=1;i<=bs;i++)
if(i==1||c[i].fi!=c[i-1].fi)
c[++tot]=c[i];

c[0]=c[tot]; c[tot+1]=c[1];//
/*c[0]=mkp((c[1].fi+q2-p2)%q2,c[1].se-1);
c[tot+1]=mkp((c[tot].fi+p2)%q2,c[tot].se+1);*/
int tp=(ll)p2*bs%q2,pls=0,pl2=a;//=a
ans=mkp(INF,INF);
for(int i=0,d;i<bs;i++,pls=((ll)pls+tp)%q2,pl2+=bs)
{
d=lower_bound(c+1,c+tot+1,mkp(((ll)q+q2-pls)%q2,0))-c-1;//-1
ans=min(ans,mkp(abs((c[d].fi+pls)%q2-q),c[d].se+pl2));
ans=min(ans,mkp(abs((c[d+1].fi+pls)%q2-q),c[d+1].se+pl2));
}
for(int i=a+bs*bs;i<=b;i++)//a+
ans=min(ans,mkp(abs((ll)p2*i%q2-q),i));
printf("%d\n",ans.se);
}
return 0;
}

posted on 2019-06-19 11:25  Narh  阅读(210)  评论(0编辑  收藏