UVALive 4270 Discrete Square Roots 模方程,数论

本文详细解析了UVALive4270 Discrete Square Roots问题的解决思路,通过数学推导说明如何寻找满足特定模方程的所有解,并提供了完整的C++实现代码。

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

// author:latstars
// time:2016-09-03 00:33:19
// 题目: UVALive 4270 Discrete Square Roots模方程
// 分类:数论,模方程
// 题意:求所有满足条件r^2=x(mod m)的r
// 题目已经给定了一个初始的r,x,m
// 不妨设新的r1^2=x(mod m)
// 那么就有r^2-r1^2=0(mod m)
// 所以就有(r+r1)(r-r1)=0(mod m)
// (r+r1)(r-r1)=k*m
// 不妨枚举a*b=n
// 使得满足(r+r1)%a=0 (r-r1)%b=0
// 那么就满足所要求的条件
// r+r1=a*k1 r-r1=a*k2
// r1=a*k1-r=r-a*k2
// 所以a*k1+b*k2=2*r
// 就是解模方程组了
// 之后把k1带入求出r1就是结果了
 // UVA - 1426 Discrete Square Roots (模方程)
// error:忘记判断模方程无解的情况
//  用while循环暴力使模数为负超时
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
using namespace std;
const int maxn=100;
typedef long long LL;
LL mx,n,r;
void exgcd(LL a,LL b,LL & d,LL & x,LL & y)
{
    if(b==0){
        x=1;y=0;d=a;
        return;
    }
    else{
        exgcd(b,a%b,d,y,x);
        y-=a/b*x;
    }
}
void cal(LL a,set<LL>& ans)
{
    LL b=n/a;
    LL d,x,y;
    exgcd(a,b,d,x,y);
    if((2*r)%d!=0)  return;
    x=x*2*r/d;
    x=(x%(b/d)+(b/d))%(b/d);
    LL r1=a*x-r;
    // while(r1>0)
    //     r1-=a*(b/d);
    while(r1<n){
        if(r1>=0&&(r1*r1)%n==mx)   ans.insert(r1);
        r1+=a*(b/d);
    }
}
void solve(void)
{
    set<LL> ans;
    LL sz=sqrt(n+0.5);
    for(LL a=1;a<=sz;a++){
        if(n%a!=0)  continue;
        cal(a,ans);
        cal(n/a,ans);
    }

    for(set<LL>::iterator it=ans.begin();it!=ans.end();it++){
        printf(" %lld",(*it));
    }
    puts("");
}
int main()
{
    int t=1;
    while(scanf("%lld %lld %lld",&mx,&n,&r)!=EOF&&(mx|n|r)){
        printf("Case %d:",t++);
        solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值