zoukankan      html  css  js  c++  java
  • BZOJ 2242 计算器

    Description

    你被要求设计一个计算器完成以下三项任务:
    (1.)给定(y,z,p),计算(y^{z};mod;P)的值;
    (2.)给定(y,z,p),计算满足(xy equiv z;mod;P)的最小非负整数;
    (3.)给定(y,z,p),计算满足(y^{x} equiv z;mod;P)的最小非负整数。

    Input

    输入包含多组数据。
    第一行包含两个正整数(T,K)分别表示数据组数和询问类型(对于一个测试点内的所有数据,询问类型相同)。
    以下行每行包含三个正整数(y,z,p),描述一个询问。

    Output

    对于每个询问,输出一行答案。对于询问类型(2)(3),如果不存在满足条件的,则输出“Orz, I cannot find x!”,注意逗号与“I”之间有一个空格。

    Sample Input

    3 1
    2 1 3
    2 2 3
    2 3 3

    Sample Output

    2
    1
    2

    Hint

    对于(100\%)的数据,(1 le y,z,P le 10^{9})(P)为质数,(1 le T le 10)

    数论裸题合集:快速幂,扩展欧几里得,bsgs。

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<map>
    using namespace std;
    
    typedef long long ll;
    int kind; ll ans;
    
    inline ll qsm(ll a,ll b,ll c)
    {
    	ll ret = 1;
    	for (;b;b >>= 1,(a *= a) %= c)
    		if (b & 1) (ret *= a) %= c;
    	return ret;
    }
    
    inline int gcd(int a,int b)
    {
    	if (!b) return a;
    	return gcd(b,a%b);
    }
    
    inline ll bsgs(int a,int b,int c)
    {
    	int i,t = 1;
    	for (i = 0;i<=50;i++)
    	{
    		if (t == b) return i;
            t = (ll)t*(ll)a% c;
    	}
    	int tmp = 1,k = 1;
    	t = 1;
    	while (tmp = gcd(a,c),tmp!=1)
    	{
    		if (b % tmp) return -1;
    		c /= tmp; k++; b /= tmp;
    		t = (ll)t*(ll)a/tmp%c;
    	}
    	int m = (int)sqrt(c+0.5);
    	map <int,int> hash; hash[1] = 0;
    	int f = 1;
    	for (i = 1;i<m;i++)
    	{
    		f = (ll)f * (ll)a % c;
    		hash[f] = i;
    	}
    	f = (ll)f*(ll)a%c;
    	b = qsm(t,c-2,c)*(ll)b%c;
    	int mod = qsm(f,c-2,c);
    	for (i = 0;i<m;i++)
    	{
    		if (hash.count(b)) return i*m+hash[b]+k-1;
    		b = (ll)b * (ll)mod % c;
    	}
    	return -1;
    }
    
    int main()
    {
    	freopen("2242.in","r",stdin);
    	freopen("2242.out","w",stdout);
    	int T; scanf("%d %d",&T,&kind);
    	while (T--)
    	{
    		int y,z,p;
    		scanf("%d %d %d",&y,&z,&p);
    		if (kind == 1) ans = qsm(y,z,p);
    		else if (kind == 2)
    		{
    			y %= p,z %= p;
    			int d = gcd(y,p);
    			if (z % d != 0) ans = -1;
    			else
    			{
    				y /= d, p /= d,z /= d;
    				ans = z*qsm(y,p-2,p)%p;
    			}
    		}
    		else ans = bsgs(y,z,p);
    		if (ans >= 0) printf("%lld
    ",ans);
    		else printf("Orz, I cannot find x!
    ");
    	}
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    __weak
    c++界面设计皮肤工具
    执行游戏时出现0xc000007b错误的解决方法
    2.4.1-Java语言基础(常量)
    句法模式识别(一)-串文法
    一步一步写算法(之hash表)
    LaTeX新人教程,30分钟从全然陌生到基本入门
    初次当面试官的经历和感触
    Android入门第八篇之GridView(九宫图)
    Android-Cannot merge new index 66195 into a non-jumbo instruction的解决的方法
  • 原文地址:https://www.cnblogs.com/mmlz/p/4463936.html
Copyright © 2011-2022 走看看