链接:https://nanti.jisuanke.com/t/41383
来源:The Preliminary Contest for ICPC Asia Xuzhou 2019
题意:给你 k 组 a b,现在有同余式 ans % b = a;求解 ans,如果 ans 不存在输出 Tankernb! ;如果 ans 存在:ans 是 fib 数输出 Lbnb!,否则输出 Zgxnb!。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<set>
#include<queue>
#include<vector>
using namespace std;
#define N 10005
#define ll long long
ll fib[100]={1,1};
ll gcd(ll a, ll b){
return b==0?a:gcd(b,a%b);
}
//求一组解(x,y)使得 ax+by=gcd(a,b),且|x|+|y|最小(注意求出的 x,y 可能为0或负数)。
//下面代码中d = gcd(a,b)
//可以扩展成求等式 ax+by=c,但c必须是d的倍数才有解,即(c%gcd(a,b))==0
void extend_gcd(ll a,ll b,ll& d,ll &x,ll &y){
if(!b){d=a;x=1;y=0;}
else{extend_gcd(b,a%b,d,y,x);y-=x*(a/b);}
}
ll inv(ll a, ll n){ //计算%n下a的逆.如果不存在逆return -1;
ll d,x,y;
extend_gcd(a,n,d,x,y);
return d==1?(x+n)%n:-1;
}
ll n[N],b[N],len,lcm;
ll work(){
for(ll i=2;i<=len;i++) {
ll A=n[1],B=n[i],d,k1,k2,c=b[i]-b[1];
extend_gcd(A,B,d,k1,k2);
if(c%d)return -1;
ll mod=n[i]/d;
ll K=((k1*(b[i]-b[1])/d)%mod+mod)%mod;
b[1]=n[1]*K+b[1];
n[1]=n[1]*n[i]/d;
}
if(b[1]==0)return lcm;
return b[1];
}
int main(){
for(int i=2;i<=91;i++) fib[i]=fib[i-1]+fib[i-2];
cin>>len;
lcm = 1;
for(int i=1;i<=len;i++) {
cin>>n[i]>>b[i];
lcm=lcm/gcd(lcm,n[i])*n[i];
}
ll n=work();//ans%b=n;ans是解
if(n>1&&n<=(ll)1e15){
bool flag=binary_search(fib,fib+92,n);
if(flag) puts("Lbnb!");
else puts("Zgxnb!");
}else puts("Tankernb!");
return 0;
}