其他分享
首页 > 其他分享> > BZOJ2242 [SDOI2011]计算器

BZOJ2242 [SDOI2011]计算器

作者:互联网

题意

<body>
F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser   autointLogout 捐赠本站
Problem 2242. -- [SDOI2011]计算器

2242: [SDOI2011]计算器

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 6231  Solved: 2448
[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,P为质数,1<=T<=10。

Sample Output

【样例输出1】
2
1
2
【样例输出2】
2
1
0

HINT

Source

第一轮day1

[Submit][Status][Discuss]

HOME Back
한국어  中文  فارسی  English  ไทย
版权所有 ©2008-2018 大视野在线测评 | 湘ICP备13009380号 Based on opensource project hustoj.

分析

数学题杂糅。

  1. 快速幂
  2. exgcd
  3. bsgs

代码

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;rg char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
    while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;

int ksm(int a,int b,int p){
    int ans=1%p;
    a%=p,b%=p-1;
    for(;b;a=(ll)a*a%p,b>>=1)
        if(b&1) ans=(ll)ans*a%p;
    return ans;
}
int exgcd(int a,int b,int&x,int&y){
    if(!b) return x=1,y=0,a;
    int d=exgcd(b,a%b,y,x);
    return y-=a/b*x,d;
}
int bsgs(int a,int b,int p){
    std::map<int,int> H;
    b%=p;
    int t=sqrt(p)+1;
    for(int i=0;i<t;++i) H[(ll)b*ksm(a,i,p)%p]=i;
    a=ksm(a,t,p);
    if(!a) return b?-1:1;
    for(int i=0,val,j;i<=t;++i){
        val=ksm(a,i,p),j=H.find(val)==H.end()?-1:H[val];
        if(j>=0&&i*t>=j) return i*t-j;
    }
    return -1;
}
int main(){
//  freopen(".in","r",stdin),freopen(".out","w",stdout);
    int t=read<int>(),k=read<int>();
    for(int y,z,p;t--;){
        read(y),read(z),read(p);
        if(k==1) printf("%d\n",ksm(y,z,p));
        else if(k==2){
            int x,t,d=exgcd(y,p,x,t);
            if(z%d) puts("Orz, I cannot find x!");
            else printf("%lld\n",((ll)x*z/d%p+p)%p);
        }
        else{
            int ans=bsgs(y,z,p);
            if(ans==-1) puts("Orz, I cannot find x!");
            else printf("%d\n",ans);
        }
    }
    return 0;
}

标签:ch,return,int,ll,ans,SDOI2011,read,BZOJ2242,计算器
来源: https://www.cnblogs.com/autoint/p/10650334.html