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;
    }
    
  • 相关阅读:
    51 Nod 1086 多重背包问题(单调队列优化)
    51 Nod 1086 多重背包问题(二进制优化)
    51 Nod 1085 01背包问题
    poj 2559 Largest Rectangle(单调栈)
    51 Nod 1089 最长回文子串(Manacher算法)
    51 Nod N的阶乘的长度 (斯特林近似)
    51 Nod 1134 最长递增子序列(经典问题回顾)
    51 Nod 1020 逆序排列
    PCA-主成分分析(Principal components analysis)
    Python中cPickle
  • 原文地址:https://www.cnblogs.com/mmlz/p/4463936.html
Copyright © 2011-2022 走看看