The Preliminary Contest for ICPC Asia Xuzhou 2019 A. Who is better? 中國剩餘定理+斐波那契博弈

題意:n是通過中國剩餘定理得到的,然後進行斐波那契博弈

題解:根據題意直接套兩個板子就可以了,這裏有個奇奇怪怪的坑,是快速乘不能用那個log的,無論如何都過不去,

用int128的就可以,用溢出那個也可以

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mem(s) memset(s, 0, sizeof(s))
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
const int maxn = 1e6+5;
const int mod = 998244353;
// inline ll q_mul(ll x,ll y,ll p){
//     ll z=(long double)x/p*y;
//     ll res=(ull)x*y-(ull)z*p;
//     return (res+p)%p;
// }
ll q_mul(ll a,ll b,ll p){
    return (__int128)a*b%p;
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0){x=1;y=0;return a;}
    ll gcd=exgcd(b,a%b,x,y);
    ll tp=x;
    x=y; y=tp-a/b*y;
    return gcd;
}

ll excrt(ll ai[],ll bi[],int n)
{
    ll x,y,k;
    ll M=bi[1],ans=ai[1];
    for(int i=2;i<=n;i++)
    {
        ll a=M,b=bi[i],c=(ai[i]-ans%b+b)%b;
        ll gcd=exgcd(a,b,x,y),bg=b/gcd;
        if(c%gcd!=0) return -1; 
        x=q_mul(x,c/gcd,bg);
        ans+=x*M;
        M*=bg;
        ans=(ans%M+M)%M;
    }
    return (ans%M+M)%M;
}
//x ≡ a(mod b)
ll a[maxn],b[maxn],k;
ll f[]={0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040,1346269,2178309,3524578,5702887,9227465,14930352,24157817,39088169,63245986,102334155,165580141,267914296,433494437,701408733,1134903170,1836311903,2971215073,4807526976,7778742049,12586269025,20365011074,32951280099,53316291173,86267571272,139583862445,225851433717,365435296162,591286729879,956722026041,1548008755920,2504730781961,4052739537881,6557470319842,10610209857723,17167680177565,27777890035288,44945570212853,72723460248141,117669030460994,190392490709135,308061521170129,498454011879264,806515533049393,1304969544928657};
int main() 
{
    int k;
    scanf("%d",&k);
    for(int i=1;i<=k;i++){
        scanf("%lld%lld",&a[i],&b[i]);
    }
    ll n=excrt(b,a,k);
    //cout<<n<<endl;
    if(n==-1){
        cout<<"Tankernb!"<<endl;
        return 0;
    }
    int flag=0;
    for(int i=1;i<=74;i++){
        if(n==f[i])flag=1;
    }
    if(flag)cout<<"Lbnb!"<<endl;
    else cout<<"Zgxnb!"<<endl;
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章