【快速幂】【扩展欧几里德】【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分别表示数据组数和询问类型(对于一个测试点内的所有数据,询问类型相同)。

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

题解:

1.快速幂。

2.扩展欧几里德。

3.BSGS,大家应该都会吧。。吾不言。

不会的可以看这里——>写的好啊!

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
#define N 100100
#define LL long long
map<LL,LL> hash;
int in(){
    int x=0; char ch=getchar();
    while (ch<‘0‘ || ch>‘9‘) ch=getchar();
    while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
    return x;
}
LL qp(LL x,LL y,LL p){
    LL z=1;
    while (y){
        if (y&1) z=(z*x)%p;
        x=(x*x)%p; y>>=1;
    }
    return z;
}
void work1(int y,int z,int p){
    printf("%lld\n",qp(y,z,p));
}
LL gcd(LL x,LL y){
    if (!y) return x;
    return gcd(y,x%y);
}
void exgcd(LL a,LL b,LL &x,LL &y){
    if (!b){
        x=1,y=0;
        return;
    }
    exgcd(b,a%b,x,y);
    LL k=x; x=y;
    y=k-a/b*y;
}
void work2(int y,int z,int p){
    LL w=gcd(y,p);
    if (z%w){
        printf("Orz, I cannot find x!\n");
        return;
    }
    LL x,k; exgcd(y,p,x,k);
    x=x*z/w; x=(x+p)%p;
    while (x<0) x+=p;
    printf("%lld\n",x);
}
void work3(int y,int z,int p){
    y%=p,z%=p; hash.clear();
    if (!y && !z){
        printf("1\n");
        return;
    }
    if (!y){
        printf("Orz, I cannot find x!\n");
        return;
    }
    LL pp=ceil(sqrt(p)),v=qp(y,p-pp-1,p),k=1;
    hash[1]=pp+1;
    for (LL i=1; i<=pp; i++){
        k=(k*y)%p;
        if (!hash[k]) hash[k]=i;
    }
    LL ans=-1;
    for (LL i=0; i<pp; i++){
        LL j=hash[z];
        if (j){
            if (j==pp+1) j=0;
            ans=(i*pp+j);
            break;
        }
        z=(z*v)%p;
    }
    if (ans==-1) printf("Orz, I cannot find x!\n");
    else printf("%lld\n",ans);
}
int main(){
    int T=in(),k=in();
    while (T--){
        int y=in(),z=in(),p=in();
        if (k==1) work1(y,z,p);
        else if (k==2) work2(y,z,p);
        else work3(y,z,p);
    }
    return 0;
}

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

时间: 2024-11-08 17:33:26

【快速幂】【扩展欧几里德】【BSGS】【SDOI 2011】【bzoj 2242】计算器的相关文章

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

题目大意:--简洁明了自己看 第一问快速幂 第二问扩展欧几里得 第三问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

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

【题解】Casting Spells LA 4975 UVa 1470 双倍回文 SDOI 2011 BZOJ 2342 Manacher

首先要吐槽LRJ,书上给的算法标签是"有难度,需要结合其他数据结构",学完Manacher才发现几乎一裸题 题目的意思是问原串中有多少个wwRwwR这样的子串,其中wR表示w的反串 比较容易看出来,wwRwwR本身是一个回文串,wwR也是一个回文串 最裸的暴力是,我们枚举每一个回文串,然后判断这个回文串的左半边是不是也是个回文串 然后我们考虑用Manacher 我们考虑Manacher的工作原理,是在充分利用原先的信息的前提下,不重复,不遗漏的枚举每个回文串 也就是说,在Manache

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;

【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&

【BZOJ 1409】 Password 数论(扩展欧拉+矩阵快速幂+快速幂)

读了一下题就会很愉快的发现,这个数列是关于p的幂次的斐波那契数列,很愉快,然后就很愉快的发现可以矩阵快速幂一波,然后再一看数据范围就......然后由于上帝与集合对我的正确启示,我就发现这个东西可以用欧拉函数降一下幂,因为两个数一定互质因此不用再加一个phi(m),于是放心的乘吧宝贝!! #include <cstdlib> #include <cstring> #include <cstdio> #include <iostream> #include &