前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >P2485 [SDOI2011]计算器

P2485 [SDOI2011]计算器

作者头像
attack
发布2018-04-13 15:36:42
7520
发布2018-04-13 15:36:42
举报
文章被收录于专栏:数据结构与算法

题目描述

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

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:

代码语言:javascript
复制
3 1
2 1 3
2 2 3
2 3 3

输出样例#1:

代码语言:javascript
复制
2
1
2

输入样例#2:

代码语言:javascript
复制
3 2
2 1 3
2 2 3
2 3 3

输出样例#2:

代码语言:javascript
复制
2
1
0

输入样例#3:

代码语言:javascript
复制
4 3
2 1 3
2 2 3
2 3 3
2 4 3

输出样例#3:

代码语言:javascript
复制
0
1
Orz, I cannot find x!
0

说明

思路:

第一问:裸快速幂

第二问:费马小定理 或者 扩展欧几里得(解ax ≡ c (mod b))

第三问:裸BSGS

对于orz的判读

首先我们把上来先把y%p,把等式的左边化成最简形式

对于第二问:先z%p,把等式右边化成最简形式,在这种条件下,如果y==0&&z!=0的情况下 y%b一定等于0而不可能等于z

对于第三问:如果y%p==0无解,因为费马小定理的条件是y与p互素

为了方便理解,我把题目中的变量p改成了mod

代码语言:javascript
复制
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<map>
 6 using namespace std;
 7 typedef long long LL;
 8 LL n,how,y,z,p;
 9 map<LL,LL>mp;
10 LL fastpow(LL a,LL p,LL mod)
11 {
12     LL base=a;LL ans=1;
13     while(p!=0)
14     {
15         if(p%2==1)ans=(ans*base)%mod;
16         base=(base*base)%mod;
17         p=p/2;
18     }
19     return ans;
20 }
21 void bsgs(LL y,LL z,LL mod)
22 {
23     mp.clear();
24     if(y%mod==0)
25     {
26         printf("Orz, I cannot find x!\n");
27         return ;
28     }
29     LL m=ceil(sqrt(mod));
30     LL ans;
31     for(LL j=0;j<=m;j++)
32     {
33         if(j==0)
34         {
35             ans=z%mod;
36             mp[ans]=1;
37             continue;
38         }
39         ans=(ans*y)%mod;
40         mp[ans]=j;
41     }
42     ans=1;
43     LL t=fastpow(y,m,mod);
44     for(LL i=1;i<=m;i++)
45     {
46         ans=(ans*t)%mod;
47         if(mp[ans])
48         {
49             LL out=i*m-mp[ans];
50             printf("%d\n",(out%mod+mod)%mod);
51             return ;
52         }
53     }
54     printf("Orz, I cannot find x!\n");
55         
56 }
57 int main()
58 {
59     scanf("%d%d",&n,&how);
60     while(n--)
61     {
62         scanf("%d%d%d",&y,&z,&p);
63         y=y%p;
64         if(how==1)
65         printf("%d\n",fastpow(y,z,p));
66         else if(how==2)
67         {
68             z%=p;
69             if(y==0&&z!=0)
70             printf("Orz, I cannot find x!\n");
71             else
72             printf("%d\n",((z%p)*(fastpow(y,p-2,p))%p)%p);
73         }
74         else if(how==3)
75         bsgs(y,z,p);
76     }
77     return 0;
78 }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-05-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目描述
  • 输入输出格式
  • 输入输出样例
  • 说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档