[类欧几里得] Maximum Sine

题目描述

给定整数a,b,p,q,设f(x)=abs(sin(p/q*πx))

找到最小的可能的整数x使f(x)最大 且 a<=x<=b

题解

  https://www.cnblogs.com/gczdajuruo/p/11008123.html

 https://www.luogu.org/problemnew/solution/P5170

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 
 5 ll f(ll n,ll a,ll b,ll c)
 6  {if(n<0) return 0;
 7   if(!n)  return b/c;
 8   if(a>=c || b>=c) return f(n,a%c,b%c,c)+n*(n+1)/2*(a/c)+(n+1)*(b/c);
 9   ll m=(a*n+b)/c;
10   return m*n-f(m-1,c,c-b-1,a);
11  }
12 
13 inline ll solve(ll l,ll r,ll a,ll b,ll c)
14  {return f(r,a,b,c)-f(l-1,a,b,c);}
15 
16 void exgcd(ll a,ll b,ll &x,ll &y)
17  {if(!b) {x=1,y=0; return;}
18       
19   exgcd(b,a%b,y,x); y-=a/b*x;
20  } 
21  
22 ll a,b,p,q;
23 inline ll get(ll p,ll q,ll t)
24  {ll gg=__gcd(p,q);
25   if(t%gg!=0) return 1e18;
26      
27   p/=gg; q/=gg; t/=gg;
28   
29   ll x,y;
30   exgcd(p,q,x,y);
31   
32   x*=t; y*=t;
33   
34   ll k=(a-x)/q; 
35   x+=k*q;
36   while(x>=a)x-=q;
37   while(x<a) x+=q;
38   return x;     
39  } 
40 inline int red() {
41   int x=0,o=1; char ch = getchar();
42   while((ch<'0' || ch>'9') && ch!='-') ch=getchar();
43   if(ch=='-')   o=-1,ch=getchar();
44   
45   while(ch>='0'&& ch<='9') x=x*10+ch-'0',ch=getchar();
46   return x*o;
47 } 
48 int main()
49  {
50  int t=red(); 
51      
52  while(t--)    
53  {a=red();b=red();p=red();q=red();
54   p*=2; q*=2; 
55   ll l=0,w=q/2,r=w;    
56   while(l<r)
57    {ll mid=(l+r)>>1;
58        ll L=w-mid,R=w+mid;
59        if(solve(a,b,p,q-L,q)-solve(a,b,p,q-R-1,q)) r=mid;
60        else                                        l=mid+1;
61    }    
62   printf("%lld\n",min(get(p,q,w-l),get(p,q,w+l)));    
63  }    
64 return 0;
65  }

q109

猜你喜欢

转载自www.cnblogs.com/YuXiaoze/p/11060714.html