[bzoj2242][SDOI2011]计算器

本文探讨了模运算中的三个核心问题:快速幂算法、扩展欧几里得算法的应用及费马小定理下的指数方程求解。通过具体算法实现,解决了特定条件下求最小非负整数解的问题。

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

Description

有三问,给出y,z,p,求
1:yzmodp
2:xyz(modp)中最小的非负整数x
3:yxz(modp)中最小的非负整数x
2,3问若无解输出Orz, I cannot find x!
y,z,p<=10^9,且p为质数
数据组数<=10,保证每一组数据都是同一问。

Solution

第一问不会的还是不要看下去了。。直接去百度快速幂。。
第二问扩展欧几里得不解释。。不会的右转百度。。
第三问貌似没有什么好做法,不过由于费马小定理的限制,答案在0~p-2之间。
那么有没有什么快速的枚举算法呢?
二分很明显直接躺,
分块?!
似乎可以,预处理处y^i(0<=i<=m,m为块的大小)
然后枚举答案存在于k这个块中,那么相对应的z乘上y^-km
因为p为质数,所以直接逆元就好了。

Code

#include<map>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
int bz,ty,sz;
ll n,m,ans,p,z,ni;
map<ll,ll> h;
bool pd;
ll exgcd(ll a,ll b,ll &x,ll &y) {
    if (!b) {x=1;y=0;return a;}
    ll xx,yy;ll gcd=exgcd(b,a%b,xx,yy);
    x=yy;y=xx-a/b*yy;return gcd;
}
ll mi(ll x,ll y) {
    ll z=x%=p;
    for(y--;y;y/=2,(x*=x)%=p) if (y&1) (z*=x)%=p;
    return z;
}
int main() {
    for(scanf("%d%d",&ty,&bz);ty;ty--) {
        scanf("%lld%lld%d",&n,&m,&p);
        if (bz==1) {
            ans=n%=p;
            for(m--;m;m/=2,(n*=n)%=p) if (m&1) (ans*=n)%=p;
            printf("%lld\n",ans);
        } else if (bz==2) {
            ll gcd=exgcd(n,p,ans,z);
            if (m%gcd) {printf("Orz, I cannot find x!\n");continue;}
            ((ans%=p)+=p)%=p;(ans*=m)%=p;
            printf("%lld\n",ans);
        } else {
            if (!(n%p)) {printf("Orz, I cannot find x!\n");continue;}
            h.clear();z=1;sz=int(sqrt(p));
            fo(i,0,sz) h[z]=i+1,(z*=n)%=p;
            ni=mi(n,(p-2)*sz);pd=0;m%=p;
            fo(i,0,p/sz) {
                if (h[m]) {pd=1;printf("%lld\n",(ll)i*sz+h[m]-1);break;}
                (m*=ni)%=p;
            }
            if (!pd) printf("Orz, I cannot find x!\n");
        }
    }
}

Ps:渣代码跑的慢。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值