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,描述一个询问。

输出格式:

输出文件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

说明






设问题给的是 a ,b p;

k==1 谁都会吧 = =

k=2:   扩展欧几里得 设d=(a,p) ,若d !| b 无解,

当d=1; 套班子,在0到p-1上有一个解

当d!=1,  套板子,最后设 t = b/d,也即是b是gcd的几倍,然后由于x和y算出来是除了d的,所以最后x要乘t,在0到p/d-1上有一个解

k=3 出门左转,EXBSGS

  1 #include"bits/stdc++.h"
  2 using namespace std;
  3 typedef long long ll;
  4
  5 ll work1(ll a,ll b,ll mod)
  6 {
  7   ll ans=1;ll base=a%mod;
  8   while (b){if(b&1)ans=(ans*base)%mod;b>>=1;base=base*base%mod;}return ans;
  9 }
 10
 11 void exgcd(ll &x,ll &y,ll a,ll b)
 12 {
 13   if(b==0){x=1,y=0;return ;}
 14   exgcd(x,y,b,a%b);ll t=x; x=y;y=(t-(a/b)*y);
 15 }
 16
 17 unordered_map <ll,ll> mp;
 18
 19
 20
 21
 22 ll bsgs(ll a,ll b,ll p)
 23 {
 24    b%=p;
 25    if(b==1)return 0; ll d; ll k=1; int cnt=0;
 26
 27    while ((d=__gcd(a,p))^1)
 28    {
 29       if(b%d)return -1;
 30       b/=d; p/=d;cnt++;
 31       k=1ll*k*(a/d)%p;
 32       if(k==b)return cnt;
 33
 34        // cout<<k<<" "<<a<<" "<<b<<" "<<p<<endl;
 35    }
 36
 37
 38
 39    int m=sqrt(p)+1; ll kt=1;
 40    mp.clear();
 41    for (int i=0;i<m;i++)
 42    {
 43      mp[1LL*kt*b%p]=i;
 44      kt=kt*a%p;
 45
 46    }
 47
 48    k=k*kt%p;
 49
 50    for (int i=1;i<=m;i++)
 51    {
 52      if(mp.find(k)!=mp.end()) return i*m-mp[k]+cnt;
 53      k=k*kt%p;
 54    }
 55
 56    return -1;
 57
 58 }
 59
 60
 61
 62
 63 int main()
 64
 65 {
 66  /*  int x,y;
 67    exgcd(x,y,3,10);
 68    cout<<(x%10+10)%10;*/
 69
 70
 71
 72
 73    ll T,k; ll y,z,p;
 74    cin>>T>>k;
 75
 76     while (T--)
 77     {  scanf("%lld%lld%lld",&y,&z,&p);
 78        if(k==1)
 79        {
 80           printf("%lld\n",work1(y,z,p));
 81        }
 82        else if(k==2)
 83        {
 84           ll Gcd=__gcd(y,p); if(z%Gcd!=0)
 85           {puts("Orz, I cannot find x!");continue;}
 86            ll x1,y1; ll t=z/Gcd;
 87            exgcd(x1,y1,y,p);
 88            p=p/Gcd;
 89          // cout<<x1<<endl;
 90            printf("%lld\n",1ll*((x1*z/Gcd)%p+p)%p);
 91        }
 92        else
 93        {
 94            ll ans=bsgs(y,z,p);
 95            if(ans!=-1)printf("%lld\n",ans);
 96           else puts("Orz, I cannot find x!");
 97         }
 98     }
 99
100 }

原文地址:https://www.cnblogs.com/zhangbuang/p/10404534.html

时间: 2024-09-28 23:36:00

P2485 [SDOI2011]计算器(快速幂+扩欧+bsgs)的相关文章

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]计算器( 快速幂 + 扩展欧几里德 + 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)

P2485 [SDOI2011]计算器

P2485 [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.L,分别表示数据组数和询问类型(对于一个测试点内的所有数 据,询问类型相同). 以下T 行每

【BZOJ2242】【SDoi2011】计算器 快速幂+EXGCD+BSGS

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]计算器_快速幂+扩展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 &

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;

Description has only two Sentences(欧拉定理 +快速幂+分解质因数)

Description has only two Sentences Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 124 Accepted Submission(s): 55   Problem Description an = X*an-1 + Y and Y mod (X-1) = 0.Your task is to calculat

【bzoj2242】[SDOI2011]计算器 数论相关(快速幂+扩展欧几里得+BSGS)

2242: [SDOI2011]计算器 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 2529 Solved: 1003 [Submit][Status][Discuss] 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)的最小非负整数. In

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&