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 行每行包含三个正整数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

说明

分析

三个模板,

  1. 快速幂,
  2. 求yx=z(mod p),转化成,yx-kp = z;可以用扩展欧几里得求解,并且要求z%gcd(y,p)!=0,(扩展欧几里得求ax+by=c:http://www.cnblogs.com/MashiroSky/p/5912977.html),         补充:因为p是质数,所以可以用费马小定理, p是质数,y与p互质,所以y有逆元,x=y^(-1)*z,y^(-1)=y^(p-2),因为0没有逆元,所以只有y=0时无解
  3. bsgs

注意,int与longlong类型,结尾的换行符

code

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

P2485 [SDOI2011]计算器的相关文章

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

bzoj2242: [SDOI2011]计算器.

2242: [SDOI2011]计算器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 4353  Solved: 1679[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

SDOI2011计算器

2242: [SDOI2011]计算器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1274  Solved: 491[Submit][Status] 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 输入包含多组

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)

【bzoj2242】[SDOI2011]计算器

2242: [SDOI2011]计算器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 3207  Solved: 1258[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

【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

[bzoj2242][Sdoi2011]计算器_exgcd_BSGS

计算器 bzoj-2242 Sdoi-2011 题目大意:裸题,支持快速幂.扩展gcd.拔山盖世 注释:所有数据保证int,10组数据. 想法:裸题,就是注意一下exgcd别敲错... ... 最后,附上丑陋的代码... ... #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <ma

【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]计算器(数论知识)

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 对于每个询问,输出一行答案.对