• 快速幂 扩欧 扩BSGS 三合一板子题


    [SDOI2011]计算器

    题目描述

    你被要求设计一个计算器完成以下三项任务:

    1、给定y、z、p,计算y^z mod p 的值;

    2、给定y、z、p,计算满足xy ≡z(mod p)的最小非负整数x;

    3、给定y、z、p,计算满足y^x ≡z(mod p)的最小非负整数x。

    为了拿到奖品,全力以赴吧!

    输入输出格式

    输入格式:

    输入文件calc.in 包含多组数据。

    第一行包含两个正整数T、K,分别表示数据组数和询问类型(对于一个测试点内的所有数

    据,询问类型相同)。

    以下T 行每行包含三个正整数y、z、p,描述一个询问。

    输出格式:

    输出文件calc.out 包括T 行.

    对于每个询问,输出一行答案。

    对于询问类型2 和3,如果不存在满足条件的,则输出“Orz, I cannot find x!”。

    输入输出样例

    输入样例#1: 复制
    3 1
    2 1 3
    2 2 3
    2 3 3
    
    输出样例#1: 复制
    2
    1
    2
    
    输入样例#2: 复制
    3 2
    2 1 3
    2 2 3
    2 3 3
    
    输出样例#2: 复制
    2
    1
    0
    
    输入样例#3: 复制
    4 3
    2 1 3
    2 2 3
    2 3 3
    2 4 3
    
    输出样例#3: 复制
    0
    1
    Orz, I cannot find x!
    0
    

    说明

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<map>
    #define ll long long 
    using namespace std;
    int T,k;
    ll a,z,p;
    map<ll,int>ha;
    ll pow(ll a,ll x)
    {
        ll ans=1;
        while(x)
        {
        if(x&1)ans=(ans*a)%p;
        a=(a*a)%p;
        x>>=1;
        }
        return ans%p;
    }
    ll gcd(ll a,ll b)
    {
        return b?gcd(b,a%b):a;
    }
    ll exgcd(ll a,ll b,ll &x,ll &y)
    {
        ll d=a;
        if(!b)x=1,y=0;
        else d=exgcd(b,a%b,y,x),y-=(a/b)*x;
        return d;
    }
    ll get(ll a,ll b)
    {
        ll x=0,y=0;
        ll d=exgcd(a,b,x,y);
        if(z%d)return -1;
        x*=(z/d);
        return (x%b+b)%b;
    }
    ll exbsgs(int a,int b,int x)
    {
        ha.clear();
        a%=x,b%=x;ll m=ceil(sqrt((double)x));
        if(b==1)return 0;
        ll tmp=1,cnt=0,D=1;
        while((tmp=gcd(a,x))!=1)
        {
        if(b%tmp)return -1;
        cnt++,b/=tmp,x/=tmp,D=(D*(a/tmp))%x;
        }
        ha[b%x]=0;ll q=1;
        for(int i=1;i<=m;i++)q=(q*a)%x,ha[q*b%x]=i;
        for(int i=1;i<=m;i++)
        {
        D=(D*q)%x;
        if(ha[D]){ll s=i*m-ha[D]+cnt;return (s%x+x)%x;}
        }
        return -1;
    }
    int main()
    {
        freopen("three.in","r",stdin);
        freopen("three.out","w",stdout);
        scanf("%d%d",&T,&k);
        for(int i=1;i<=T;i++)
        {
        scanf("%lld%lld%lld",&a,&z,&p);
        if(k==1)printf("%lld
    ",pow(a,z));
        else if(k==2)
        {
            ll ans=get(a,p);
            if(ans==-1)puts("Orz, I cannot find x!");
            else printf("%lld
    ",ans);
        }
        else
        {
            ll ans=exbsgs(a,z,p);
            if(ans==-1)puts("Orz, I cannot find x!");
            else printf("%lld
    ",ans);
        }
        }
        return 0;
    }
  • 相关阅读:
    centos 下PATH变量配置错误补救办法 Alex
    基于php模块方式安装LAMP和常见LAMP应用 Alex
    php配置 Alex
    php测试小代码 Alex
    PHP简介 Alex
    2.7.JavaScriptnull与undefined
    2.9.JavaScript内置对象
    2.8.JavaScript不同数据类型转换
    2.2.javascript变量作用域
    2.6.Javascript数值型
  • 原文地址:https://www.cnblogs.com/lxykk/p/8343453.html
Copyright © 2020-2023  润新知