BZOJ-2242 计算器 快速幂+拓展欧几里得+BSGS(数论三合一)
来源:互联网 发布:怎么使用爬虫软件 编辑:程序博客网 时间:2024/04/30 07:37
污污污污
2242: [SDOI2011]计算器
Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 2312 Solved: 917
[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)的最小非负整数。
Input
输入包含多组数据。
第一行包含两个正整数T,K分别表示数据组数和询问类型(对于一个测试点内的所有数据,询问类型相同)。
以下行每行包含三个正整数y,z,p,描述一个询问。
Output
对于每个询问,输出一行答案。对于询问类型2和3,如果不存在满足条件的,则输出“Orz, I cannot find x!”,注意逗号与“I”之间有一个空格。
Sample Input
【样例输入1】
3 1
2 1 3
2 2 3
2 3 3
【样例输入2】
3 2
2 1 3
2 2 3
2 3 3
【数据规模和约定】
对于100%的数据,1<=y,z,p<=10^9,为质数,1<=T<=10。
Sample Output
【样例输出1】
2
1
2
【样例输出2】
2
1
0
HINT
Source
第一轮day1
第一问:快速幂直接搞;第二问:拓展欧几里得直接搞;第三问:BSGS直接搞;
安利一下BSGS的大体框架:
首先要求 a^x=b (mod c)
假定x=im-j (m=ceil(sqrt(n)))
那么进行变换:
a^im = b*a^j (mod c)
枚举b*a^j mod p的值存入哈希表(map)。
再枚举a^im的值,从哈希表里找,如果能找到一样的答案就是i*m-j
#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>#include<cmath>#include<map>using namespace std;int n;int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f;}int gcd(int a,int b){ if (!b) return a; else return gcd(b,a%b);}void exgcd(int a,int b,int &x,int &y){ if (!b) {x=1,y=0;return;} exgcd(b,a%b,x,y); int t=x;x=y; y=t-a/b*y;}long long quick_pow(long long a,int b,int p)//返回a^b%p的值{ long long re=1; long long tmp=a%p; while (b) { if (b&1) re=(re*tmp)%p; tmp=(tmp*tmp)%p; b=b>>1; } return re;}void work1(int a,int b,int c) { printf("%lld\n",quick_pow(a,b,c));}void work2(int a,int b,int c) { c=-c; int gc=gcd(a,c); if (b%gc!=0) {puts("Orz, I cannot find x!");return;} a/=gc;b/=gc;c/=gc; int x,y;exgcd(a,c,x,y); x=(long long)x*b%c; while (x<0) x+=c; printf("%d\n",x);}void work3(int a,int b,int c){ map<int,int>mp;mp.clear(); if (a%c==0) {puts("Orz, I cannot find x!");return;} int m=ceil(sqrt(c)); long long t=b; for (int i=0; i<=m; i++) { mp[(int)t]=i; t=t*a%c; } int s=quick_pow(a,m,c);t=s; for (int i=1; i<=m; i++) { int v=mp[(int)t]; if (v!=0) {printf("%d\n",i*m-v);return;} t=t*s%c; } puts("Orz, I cannot find x!");}int main(){ int t=read(),k=read(); for (int i=1; i<=t; i++) { int y=read(),z=read(),p=read(); if (k==1) work1(y,z,p); if (k==2) work2(y,z,p); if (k==3) work3(y,z,p); } return 0;}
- BZOJ-2242 计算器 快速幂+拓展欧几里得+BSGS(数论三合一)
- BZOJ 2242 SDOI2011 计算器 快速幂+扩展欧几里得+BSGS
- bzoj 2242 [SDOI2011]计算器 快速幂+扩展欧几里得+BSGS
- 【bzoj2242】[SDOI2011]计算器 数论相关(快速幂+扩展欧几里得+BSGS)
- bzoj 2242(快速幂+扩展欧几里得+BSGS)
- 【SDOI2011】【BZOJ】【P2242】【计算器】【题解】【快速幂+扩展欧几里得+高次同余方程/BSGS】
- [BZOJ2242][SDOI2011][BSGS][拓展欧几里得]计算器
- 【快速幂】【扩展欧几里德】【BSGS】【SDOI 2011】【bzoj 2242】计算器
- BZOJ 2242 [SDOI2011]计算器 BSGS+快速幂+EXGCD
- 【bzoj】 - 2242 计算器 【BSGS】
- [BZOJ2242]SDOI2011计算器|快速幂|扩展欧几里得|BSGS
- BZOJ_P2242&Codevs_P1565[SDOI2011]计算器(快速幂+扩展欧几里得+BSGS)
- BZOJ 1965 快速幂 + 拓展欧几里得
- bzoj 2242 [sdoi2011]计算器 (BSGS)
- BZOJ-2242-计算器-SDOI2011-BSGS
- bzoj 2242: [SDOI2011]计算器 BSGS
- Bzoj 2242: [SDOI2011]计算器(BSGS)
- BZOJ-1951 古代猪文 (组合数取模Lucas+中国剩余定理+拓展欧几里得+快速幂)
- 腾讯云下的应用
- android 屏幕适配
- 树莓派2安装win 10 IoT
- 源码安装zabbix3.0.0
- CxImage给图片加水印文字
- BZOJ-2242 计算器 快速幂+拓展欧几里得+BSGS(数论三合一)
- DICOM 簡介
- UVA 524 / hdu 1016 Prime Ring Problem
- 文章标题
- 移动前端开发经验指南
- 使用wget做站点镜像及wget的高级用法
- android 美团多渠道打包详解
- MyCat - 源代码篇(2)
- Android NDK 编译FFMPEG 问题