码迷,mamicode.com
首页 > 其他好文 > 详细

计算器(bzoj 2242)

时间:2017-03-06 23:41:09      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:tin   类型   注意   整数   bool   规模   color   输出   data   

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
/*
  Type1:快速幂
  Type2:扩展欧几里得
  Type3:BSGS 
*/
#include<cstdio>
#include<iostream>
#include<map>
#include<cmath>
#define lon long long
using namespace std;
int Q,op;lon A,B,C;
map<lon,int> hash;
lon poww(lon a,lon b){
    lon base=a,r=1;
    while(b){
        if(b&1) r*=base;r%=C;
        base*=base;base%=C;
        b>>=1;
    }
    return r;
}
lon exgcd(lon a,lon b,lon &x,lon &y){
    if(!b) {
        x=1;y=0;return a;
    }
    lon r=exgcd(b,a%b,x,y);
    lon t=x;x=y;y=t-a/b*y;
    return r;
}
void work3(){
    hash.clear();
    if(A%C==0){
        printf("Orz, I cannot find x!\n");
        return;
    }
    lon m=ceil(sqrt(C)),ans;
    for(int i=0;i<=m;i++){
        if(!i){
            ans=B%C;hash[ans]=i;
            continue;
        }
        ans=(ans*A)%C;hash[ans]=i;
    }
    ans=1;lon t=poww(A,m);bool fl=false;
    for(int i=1;i<=m;i++){
        ans=(ans*t)%C;
        if(hash[ans]){
            ans=i*m-hash[ans];
            ans=(ans+C+C)%C;
            printf("%lld\n",ans);
            fl=true;
            break;
        }
    }
    if(!fl) printf("Orz, I cannot find x!\n");
}
void work2(){
    lon x,y,vgcd;
    vgcd=exgcd(A,C,x,y);
    if(B%vgcd) {
        printf("Orz, I cannot find x!\n");
        return;
    }
    x=x*B/vgcd;
    lon mod=C/vgcd;
    x=((x%mod)+mod)%mod;
    printf("%lld\n",x);
}
void work1(){
    printf("%lld\n",poww(A,B));
}
int main(){
    scanf("%d%d",&Q,&op);
    while(Q--){
        scanf("%lld%lld%lld",&A,&B,&C);
        if(op==1) work1();
        if(op==2) work2();
        if(op==3) work3();
    }
    return 0;
}

 

计算器(bzoj 2242)

标签:tin   类型   注意   整数   bool   规模   color   输出   data   

原文地址:http://www.cnblogs.com/harden/p/6512358.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!