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 ll;
typedef pair<ll,ll> abcd;
ll A,B,C,D,hash_table[M],val[M],tim[M],tot;
int Hash(ll x)
{
    int pos=x%M;
    while(1)
    {
        if(tim[pos]!=tot)
            tim[pos]=tot,hash_table[pos]=-1,val[pos]=0x3f3f3f3f;
        if(hash_table[pos]==-1||hash_table[pos]==x)
            return hash_table[pos]=x,pos;
        else
            ++pos,pos%=M;
    }
}
int Get_Hash(ll x)
{
    int pos=x%M;
    while(1)
    {
        if(tim[pos]!=tot)
            tim[pos]=tot,hash_table[pos]=-1;
        if(hash_table[pos]==-1)
            return -1;
        if(hash_table[pos]==x)
            return pos;
        else
            ++pos,pos%=M;
    }
}
ll GCD(ll x,ll y)
{
    return y?GCD(y,x%y):x;
}
abcd EXGCD(ll x,ll y)
{
    if(!y) return abcd(1,0);
    abcd temp=EXGCD(y,x%y);
    return abcd(temp.second,temp.first-x/y*temp.second);
}
ll Inverse(ll x)
{
    ll temp=EXGCD(x,C).first;
    return (temp%C+C)%C;
}
ll EXBSGS()
{
    ll i,m,cnt=0,temp,base=1;
    int pos;
    B%=C;
    for(i=0,temp=1%C;i<=50;i++,temp*=A,temp%=C)
        if(temp==B)
            return i;
    D=1;
    while(temp=GCD(A,C),temp!=1)
    {
        if(B%temp)
            return -1;
        ++cnt;
        B/=temp;
        C/=temp;
        D*=A/temp;
        D%=C;
    }
    B*=Inverse(D);B%=C;
    m=(ll)ceil(sqrt(C)+1e-5);
    ++tot;
    for(i=0,temp=1%C;i<m;i++,temp*=A,temp%=C)
        pos=Hash(temp),val[pos]=min(val[pos],i);
    for(i=1,base=1%C;i<=m;i++,base*=A,base%=C);
    for(i=0,D=1%C;i<m;i++,D*=base,D%=C)
    {
        temp=EXGCD(D,C).first*B;
        temp=(temp%C+C)%C;
        pos=Get_Hash(temp);
        if(~pos)
            return i*m+val[pos]+cnt;
    }
    return -1;
}
ll KSM()
{
	ll re=1;
	while(B)
	{
		if(B&1)re*=A,re%=C;
		A*=A,A%=C;
		B>>=1;
	}
	return re;
}
ll EXGCD()
{
	if(A%C==0&&B%C!=0)
		return -1;
	return (EXGCD(A,C).first%C*B%C+C)%C;
}
int main()
{
	int T,k;
	ll ans;
	for(cin>>T>>k;T;T--)
	{
		cin>>A>>B>>C;
		switch(k)
		{
			case 1:ans=KSM();break;
			case 2:ans=EXGCD();break;
			case 3:ans=EXBSGS();break;
		}
		if(ans==-1)
			puts("Orz, I cannot find x!");
		else
			cout<<ans<<endl;
	}
}
时间: 2024-10-12 22:30:35

BZOJ 2242 SDOI2011 计算器 快速幂+扩展欧几里得+BSGS的相关文章

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]计算器(快速幂+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 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;

bzoj 2242 [SDOI2011]计算器(数论知识)

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 对于每个询问,输出一行答案.对

[原博客] BZOJ 2242 [SDOI2011] 计算器

题目链接 noip级数论模版题了吧.让求三个东西: 给定y,z,p,计算Y^Z Mod P 的值. 给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数. 给定y,z,p,计算满足Y^x ≡ Z ( mod P)的最小非负整数. 其中P均为素数.来分着处理. 1 y^z%p 快速幂.推荐一种又快又好写的写法. 1 LL power_mod(LL a,LL b,LL p){ //get a^b%p 2 LL ret=1; 3 while(b){ 4 if(b&1) ret = re

bzoj 2242: [SDOI2011]计算器 &amp; BSGS算法笔记

这题的主要难点在于第三问该如何解决 于是就要知道BSGS是怎样的一种方法了 首先BSGS是meet in the middle的一种(戳下面看) http://m.blog.csdn.net/blog/zentropy/11200099 看完链接后再看以下内容 --------------------------------------------------------------------------------------------------------------------- 对

【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

【快速幂】【扩展欧几里德】【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

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