HDU - 5478 Can you find it

本文解析了HDU-5478题目,这是一个关于求解特定数学公式的竞赛题,通过欧拉定理和快速幂运算,讨论了如何找到满足条件的所有整数对(a, b)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HDU - 5478 Can you find it

传送门HDU - 5478

题意

给你 C C ,k1, b1 b 1 , k2 k 2 ,( C C 为质数)。
让你求公式

ak1×n+b1+bk2×nk2+1=0(modC)(n=1,2,3,4)

所有使等式成立的 (a,b)(1a,b<C) ( a , b ) ( 1 ≤ a , b < C ) ,没有输出-1。

题解

第一眼看见这个题,因为C是质数,第一反应是欧拉降幂。但是欧拉降幂好像没啥卵用orz。
贴个欧拉降幂公式。

AB(modC)=AB(modϕ(C))+ϕ(C)(modC) A B ( mod C ) = A B ( mod ϕ ( C ) ) + ϕ ( C ) ( mod C )

两个未知量,那么就要两个等式就能求出来 a a b。那么我们就直接列出 n=1 n = 1 n=2 n = 2 的式子。
ak1+b1+b=0(modC)(1) (1) a k 1 + b 1 + b = 0 ( mod C )

a2×k1+b1+bk2+1=0(modC)(2) (2) a 2 × k 1 + b 1 + b k 2 + 1 = 0 ( mod C )

通过 (1) ( 1 ) a a b的范围,我们可以算得
b=(cak1+b1)(3) (3) b = ( c − a k 1 + b 1 )

然后我们把 (1)(2) ( 1 ) ( 2 ) 移项, (2) ( 2 ) 除以 (1) ( 1 )
a2×k1+b1ak1+b1=bk2+1b a 2 × k 1 + b 1 a k 1 + b 1 = − b k 2 + 1 − b

上下约分得
ak1=bk2(4) (4) a k 1 = b k 2

这样算法就明了了,我们可以枚举 a a ,然后通过(1)求出 b b
再用快速幂验证(4)是否成立,如果成立就输出。

ac代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#include <iomanip>
//#include <unordered_map>

#pragma comment(linker, "/STACK:102400000,102400000")
#define fir first
#define sec second
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define clr(x) memset(x,0,sizeof(x))
#define cld(x) memset(x,-1,sizeof(x))
#define clx(x) memset(x,63,sizeof(x))
#define cln(x) memset(x,-64,sizeof(x))
#define rush() int T;scanf("%d",&T);while(T--)
#define pi 3.1415926
#define VM 100047
#define EM 400047
#define rd(x) scanf("%d",&x);

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>pii;
typedef pair<ll,ll>pll;

const int inf = 0x3f3f3f3f;
const ll llf = 0x3f3f3f3f3f3f3f3f;
const int maxn = (int) 1e6 + 7;
const double eps = 1e-10;
const ll mod1 = (int) 1e9 + 7;
const ll mod2 = 998244353;
const ll has = 99959;
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};

ll pow(ll x, ll n, ll mod) {
    ll res = 1;
    while (n > 0) {
        if (n % 2 == 1) {
            res = res * x;
            res = res % mod;
        }
        x = x * x;
        x = x % mod;
        n >>= 1;
    }
    return res;
}

int main(){
    std::ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
#endif

        ll c,k1,b1,k2;
        int NUM = 0;
        while(cin >> c >> k1 >> b1 >> k2){
            bool flag = false;
            cout << "Case #" << ++NUM << ":" << endl;
            for (int i = 1; i < c; i++) {
                ll a = i;
                ll l = pow(a,k1 + b1,c);
                ll b = (c - l);
                if(pow(a,k1,c) == pow(b,k2,c)){
                    flag = true;
                    cout << a << " " << b << endl;
                }
            }
            if(!flag){
                cout << -1 << endl;
            }

        }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值