hdu5478Can you find it

//求出所有(a^(k1*n+b1)+b^(k2*n-k2+1))%c == 0 的a,b
//对于所有的n都成立
//n = 1时(a^(k1+b1) + b)%c
//枚举i找出对应的b
//感觉应该有循环节
//对于每一对成立的(a,b)找出对应的循环节
//然后就过了
#include<cstdio>
#include<cstring>
#include<iostream>
#include<map>
using namespace std ;
const int maxn = 2e5+10 ;
typedef long long ll ;
ll mod ,k1 , k2 , b1 ;
ll pow(ll a , ll k)
{
    ll c = 1 ;
    while(k)
    {
        if(k&1)c = c*a%mod ;
        a = a*a%mod ;
        k >>= 1 ;
    }
    return c ;
}
map<pair<ll , ll> , int>ma ;
bool ans[maxn] ;
int judge(ll a , ll b)
{
    ma.clear() ;
    for(ll i = 1;;i++)
    {
        ll t1 = pow((ll)a , k1*i+b1) ;
        ll t2 = pow((ll)b , k2*i-k2+1) ;
        pair<ll ,ll> tmp = make_pair(t1 , t2) ;
        if((t1+t2)%mod != 0)
        return -1 ;
        if(ma[tmp])
        return i;
        ma[tmp] = 1;
    }
}
int main()
{
    //freopen("in.txt" , "r" , stdin) ;
    int cas = 0 ;
    while(~scanf("%lld%lld%lld%lld" , &mod  , &k1 , &b1 , &k2))
    {
        printf("Case #%d:\n" , ++cas) ;
        bool flag = false ;
        for(int i = 1;i < mod;i++)
        {
            ll t1 = pow(i , k1+b1) ;
            if(t1 == 0)continue ;
            ll t2 = mod-t1 ;
            if(judge(i , t2) != -1)
            printf("%d %d\n" , i , t2) ,flag = true ;
        }
        if(!flag)puts("-1") ;
    }
    return 0 ;
}

你可能感兴趣的:(hdu5478Can you find it)