2019 Xuzhou A. Who is better?(中国剩余定理 - 求最小正整数解)

链接: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;
}
发布了166 篇原创文章 · 获赞 68 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_42217376/article/details/100667226