zoukankan      html  css  js  c++  java
  • 洛谷 P2485 [SDOI2011]计算器 解题报告

    P2485 [SDOI2011]计算器

    题目描述

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

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

    输出格式:

    输出文件calc.out 包括T 行.

    对于每个询问,输出一行答案。

    对于询问类型2 和3,如果不存在满足条件的,则输出“Orz, I cannot find x!”。

    说明:


    T1快速幂

    T2逆元orexgcd

    无解看看y可不可以整除p

    T3 bsgs
    从算法竞赛进阶指南上学习的,注意点写了注释


    Code:

    #include <cstdio>
    #include <cmath>
    #include <map>
    #define ll long long
    ll quickpow(ll d,ll k,ll p)
    {
        ll f=1;
        while(k)
        {
            if(k&1) f=f*d%p;
            d=d*d%p;
            k>>=1;
        }
        return f;
    }
    ll work1(ll y,ll z,ll p)
    {
        return quickpow(y,z,p);
    }
    ll work2(ll y,ll z,ll p)//xy=z mod p
    {
        if(y%p==0&&z!=0) return -1;
        return z*quickpow(y,p-2,p)%p;
    }
    std::map <ll,ll > Hash;
    ll work3(ll y,ll z,ll p)//y^x=z mod p
    {
        Hash.clear();//清空
        z%=p;//注意先取膜
        ll t=sqrt(p)+1;//注意向上取整
        for(ll i=0;i<t;i++)
            Hash[1ll*z*quickpow(y,i,p)%p]=i;
        y=quickpow(y,t,p);//根号次方
        if(y==0) return z==0?1:-1;//特判一下
        for(ll k,j,i=0;i<=t;i++)
        {
            k=quickpow(y,i,p);
            j=Hash.find(k)==Hash.end()?-1:Hash[k];
            if(i*t-j>=0&&~j)//试试 2 2 3这样的情况?
                return i*t-j;
        }
        return -1;
    }
    int main()
    {
        int t,k;
        scanf("%d%d",&t,&k);
        while(t--)
        {
            ll y,z,p;
            scanf("%lld%lld%lld",&y,&z,&p);
            if(k==1) printf("%lld
    ",work1(y,z,p));
            else if(k==2)
            {
                ll ans=work2(y,z,p);
                if(~ans) printf("%lld
    ",ans);
                else printf("Orz, I cannot find x!
    ");
            }
            else
            {
                ll ans=work3(y,z,p);
                if(~ans) printf("%lld
    ",ans);
                else printf("Orz, I cannot find x!
    ");
            }
        }
        return 0;
    }
    
    

    2018.9.11

  • 相关阅读:
    BZOJ3697: 采药人的路径
    解题:WC 2007 石头剪刀布
    解题:CQOI 2017 老C的方块
    解题:洛谷4314 CPU监控
    解题:CQOI 2017 老C的任务
    解题:CF1009 Dominant Indices
    解题:CF570D Tree Requests
    解题:APIO 2012 派遣
    解题:ZJOI 2015 幻想乡战略游戏
    解题:洛谷4178 Tree
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9627717.html
Copyright © 2011-2022 走看看