BZOJ 2242 [SDOI2011]计算器 BSGS+快速幂+EXGCD

题意:链接

方法: BSGS+快速幂+EXGCD

解析:

BSGS…

题解同上..

代码:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MOD 140345
using namespace std;
typedef long long ll;
ll t,k,ans;
ll y,z,p;
int head[MOD+10],cnt;
struct node
{
    ll from,to,val,next;
}edge[MOD+10];
void init()
{
    memset(head,-1,sizeof(head));
    cnt=1;
}
void edgeadd(ll from,ll to,ll val)
{
    edge[cnt].from=from,edge[cnt].to=to,edge[cnt].val=val;
    edge[cnt].next=head[from];
    head[from]=cnt++;
}
ll quick_my(ll x,ll y)
{
    ll ret=1;
    while(y)
    {
        if(y&1)ret=(ret*x)%p;
        x=(x*x)%p;
        y>>=1;
    }
    return ret;
}
void exgcd(ll a,ll b,ll &x,ll &y,ll &gcd)
{
    if(!b)
    {
        x=1,y=0,gcd=a;
        return;
    }
    exgcd(b,a%b,y,x,gcd);
    y=y-a/b*x;
}
void BSGS(ll A,ll B,ll C)
{
    //A^x=B(mod C)
    ll m=(int)ceil(sqrt(C));
    ll k=1;
    for(int i=0;i<m;i++)
    {
        int flag=1;
        for(int j=head[k%MOD];j!=-1;j=edge[j].next)
        {
            if(edge[j].val==k){flag=0;continue;}
        }
        if(flag)edgeadd(k%MOD,i,k);
        k=k*A%C;
    }
    ll X,Y,GCD;
    exgcd(k,C,X,Y,GCD);
    ll invk=(X%C+C)%C;
    ll D=1,invD=1;
    for(int i=0;i<=m;i++)
    {
        ll tmpB=B*invD%C;
        for(int j=head[tmpB%MOD];j!=-1;j=edge[j].next)
        {
            if(edge[j].val==tmpB){ans=i*m+edge[j].to;return;}
        }
        D=D*k%C;
        invD=invD*invk%C;
    }
}
int main()
{
    scanf("%lld%lld",&t,&k);
    switch(k)
    {
        case 1:
            while(t--)
            {
                scanf("%lld%lld%lld",&y,&z,&p);
                printf("%lld\n",quick_my(y,z));
            }
            break;
        case 2:
            while(t--)
            {
                ll x,tmp,gcd;
                scanf("%lld%lld%lld",&y,&z,&p);
                exgcd(y,p,x,tmp,gcd);
                if(z%gcd!=0)puts("Orz, I cannot find x!");
                else
                {
                    ll mod=p/gcd;
                    printf("%lld\n",((x*z/gcd)%mod+mod)%mod);
                }
            }
            break;
        case 3:
            while(t--)
            {
                init();
                scanf("%lld%lld%lld",&y,&z,&p);
                ans=-1;
                if(y%p==0&&z!=0){puts("Orz, I cannot find x!");continue;}
                BSGS(y,z,p);
                if(ans==-1)puts("Orz, I cannot find x!");
                else printf("%lld\n",ans);
            }
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 12:26:27

BZOJ 2242 [SDOI2011]计算器 BSGS+快速幂+EXGCD的相关文章

BZOJ 2242 [SDOI2011]计算器(快速幂+Exgcd+BSGS)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2242 [题目大意] 给出T和K 对于K=1,计算 Y^Z Mod P 的值 对于K=2,计算满足 xy≡ Z ( mod P ) 的最小非负整数 对于K=3,计算满足 Y^x ≡ Z ( mod P) 的最小非负整数 [题解] K=1情况快速幂即可 K=2情况用exgcd求解 K=3用BSGS求解 [代码] #include <cstdio> #include <cmath&

bzoj 2242: [SDOI2011]计算器 &amp; BSGS算法笔记

这题的主要难点在于第三问该如何解决 于是就要知道BSGS是怎样的一种方法了 首先BSGS是meet in the middle的一种(戳下面看) http://m.blog.csdn.net/blog/zentropy/11200099 看完链接后再看以下内容 --------------------------------------------------------------------------------------------------------------------- 对

BZOJ 2242: [SDOI2011]计算器( 快速幂 + 扩展欧几里德 + BSGS )

没什么好说的... --------------------------------------------------------------------- #include<cstdio> #include<cmath> #include<map> using namespace std; typedef long long ll; int MOD; void gcd(int a, int b, int& d, int& x, int& y)

BZOJ 2242 SDOI2011 计算器 快速幂+扩展欧几里得+BSGS

题目大意:--简洁明了自己看 第一问快速幂 第二问扩展欧几里得 第三问BSGS 顺便一开始没看到p是质数0.0 去弄了EXBSGS的模板0.0 懒得改了 #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 1001001 using namespace std; typedef long long l

bzoj 2242 [SDOI2011]计算器(数论知识)

Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数: 3.给定y,z,p,计算满足Y^x ≡ Z ( mod P)的最小非负整数. Input 输入包含多组数据. 第一行包含两个正整数T,K分别表示数据组数和询问类型(对于一个测试点内的所有数据,询问类型相同). 以下行每行包含三个正整数y,z,p,描述一个询问. Output 对于每个询问,输出一行答案.对

[原博客] BZOJ 2242 [SDOI2011] 计算器

题目链接 noip级数论模版题了吧.让求三个东西: 给定y,z,p,计算Y^Z Mod P 的值. 给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数. 给定y,z,p,计算满足Y^x ≡ Z ( mod P)的最小非负整数. 其中P均为素数.来分着处理. 1 y^z%p 快速幂.推荐一种又快又好写的写法. 1 LL power_mod(LL a,LL b,LL p){ //get a^b%p 2 LL ret=1; 3 while(b){ 4 if(b&1) ret = re

BZOJ_2242_[SDOI2011]计算器_快速幂+扩展GCD+BSGS

题意: 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数: 3.给定y,z,p,计算满足Y^x ≡ Z ( mod P)的最小非负整数. 分析: 各种板子题 代码: // luogu-judger-enable-o2 // luogu-judger-enable-o2 #include <stdio.h> #include <string.h> #include &

P2485 [SDOI2011]计算器(快速幂+扩欧+bsgs)

题目描述 你被要求设计一个计算器完成以下三项任务: 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,描述一个询问

【快速幂】【扩展欧几里德】【BSGS】【SDOI 2011】【bzoj 2242】计算器

2242: [SDOI2011]计算器 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 2077 Solved: 812 Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数: 3.给定y,z,p,计算满足Y^x ≡ Z ( mod P)的最小非负整数. Input 输入包含多组数据. 第一行包含两个正整数T,K