题解:P10383 「HOI R1」杂分选约
更好的阅读体验
学生零太强大了。
考虑到题目保证了
则我们声称,取一个大质数
由定义
\frac{p}{q} \equiv \frac{x}{y} \pmod {P} 。那么
py \equiv qx \pmod {P} ,即py - qx = kP, k \isin \N 。显然
py - qx < V^2, kP > V^2 ,因此py - qx = 0 ,即\frac{p}{q} = \frac{x}{y} 。
现在要解同余方程
那么可以 BSGS。设一个阈值
接下来我们枚举
我们可以把
那么这道题就做完了,理论上
要卡常,快读是贺 Purslane 的。
#include<bits/stdc++.h>
#define endl '\n'
#define N 1000006
using namespace std;
using i64=long long;
using i128=__int128;
constexpr i128 MOD=(i128)9000000000000000041;
constexpr int B=1e4,iB=3e5;
int n,m,_,tot;
i128 t,ma=1,mb=1,val,ival,num[iB+6];
inline void write(i128 k)
{
if(k<0)putchar('-'),k=-k;
int nnum[40],ttp=0;
while(k)nnum[++ttp]=k%10,k/=10;
if(!ttp)nnum[++ttp]=0;
while(ttp)putchar(nnum[ttp--]^48);
}
class IO_helper{ // by purslane
private:
static const int L = 1 << 16;
char in_buf[L], *in_st, *out_st;
char _getc(){
if (in_st == out_st)
{
out_st = (in_st = in_buf) + fread(in_buf, 1, L, stdin);
if (in_st == out_st) return EOF;
}
return *in_st++;
}
public:
template <typename IntType>
IO_helper &operator>>(IntType &x){
bool ok=0;
char c; while ((c = _getc()) < '0' || c > '9')ok|=c=='-';
for (x = 0; c >= '0' && c <= '9'; c = _getc())
x = x * 10 + c - '0';
x=(ok?-x:x);
return *this;
}
} IO;
i128 qpow(i128 x,i128 y=MOD-2)
{
i128 ret=1;
for(;y;y>>=1,x=x*x%MOD)if(y&1)ret=ret*x%MOD;
return ret;
}
i128 gcd128(i128 x,i128 y) {return y?gcd128(y,x%y):x;}
int check(i128 p)
{
i128 q=ival*p%MOD;
if(p&&q&&p<=3e9&&q<=3e9)
{
i128 g=gcd128(p,q);
p/=g,q/=g,write(p),putchar(32),write(q),putchar(10);
return 1;
}
return 0;
}
int lb(i128 x)
{
int l=1,r=tot,ret=tot+1;
while(l<=r)
{
int mid=l+r>>1;
if(num[mid]>x)ret=mid,r=mid-1;
else l=mid+1;
}
return ret;
}
main()
{
IO>>n>>m>>_;
for(int i=1;i<=n;i++)IO>>t,ma=ma*t%MOD;
for(int i=1;i<=m;i++)IO>>t,mb=mb*t%MOD;
val=ma*qpow(mb)%MOD,ival=qpow(val);
for(int i=0;i<iB;i++)num[++tot]=i*B*val%MOD;
sort(num+1,num+1+tot);
for(int i=0,it;i<B;i++)
{
i128 b=(MOD-i*val%MOD)%MOD;
it=lb(b);
if(it<=tot&&check((i*val+num[it])%MOD))return 0;
it=lb(0);
if(it<=tot&&check((i*val+num[it])%MOD))return 0;
}
write(val),printf(" 1\n");
return 0;
}