zoukankan      html  css  js  c++  java
  • [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
    对于每个询问,输出一行答案。对于询问类型2和3,如果不存在满足条件的,则输出“Orz, I cannot find x!”,注意逗号与“I”之间有一个空格。

    Sample Input 1
    3 1
    2 1 3
    2 2 3
    2 3 3

    Sample Output 1
    2
    1
    2

    Sample Input 2
    3 2
    2 1 3
    2 2 3
    2 3 3

    Sample Output 2
    2
    1
    0

    Sample Input 3
    4 3
    2 1 3
    2 2 3
    2 3 3
    2 4 3

    Sample Output 3
    0
    1
    Orz, I cannot find x!
    0

    HINT
    对于100%的数据,1<=y,z,p<=10^9,P为质数,1<=T<=10。


    我们把子任务分开处理。
    第一个快速幂即可
    第二个扩展欧几里得即可
    第三个BSGS即可
    这题做完了(其实是我懒得讲BSGS,推荐一个写的不错的博客)

    /*program from Wolfycz*/
    #include<map>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x>=10)	print(x/10);
    	putchar(x%10+'0');
    }
    namespace quick_mod{
    	int mlt(int a,int b,int p){
    		int res=1;
    		for (;b;b>>=1,a=1ll*a*a%p)	if (b&1)	res=1ll*res*a%p;
    		return res;
    	}
    	void main(int T){
    		for (int i=1;i<=T;i++){
    			int a=read(),b=read(),p=read();
    			printf("%d
    ",mlt(a,b,p));
    		}
    	}
    };
    namespace exgcd_solve{
    	int gcd(int a,int b){return !b?a:gcd(b,a%b);}
    	void exgcd(int a,int b,int &x,int &y){
    		if (!b){x=1,y=0;return;}
    		exgcd(b,a%b,x,y);
    		int t=x; x=y,y=t-a/b*y;
    	}
    	void main(int T){
    		for (int i=1;i<=T;i++){
    			int a=read(),c=read(),b=read(),x,y;
    			int d=gcd(a,b);
    			if (c%d){
    				printf("Orz, I cannot find x!
    ");
    				continue;
    			}
    			a/=d,b/=d,c/=d;
    			exgcd(a,b,x,y);
    			x=(1ll*x*c%b+b)%b;
    			printf("%d
    ",x);
    		}
    	}
    };
    namespace BSGS_solve{
    	map<int,int>mp;
    	int mlt(int a,int b,int p){
    		int res=1;
    		for (;b;b>>=1,a=1ll*a*a%p)	if (b&1)	res=1ll*res*a%p;
    		return res;
    	}
    	int gcd(int a,int b){return !b?a:gcd(b,a%b);}
    	int work(int a,int b,int p){
    		a%=p,b%=p;
    		int d=gcd(a,p),t=1,cnt=0;
    		while (d!=1){
    			if (b%d)	return -1;
    			p/=d,b/=d,t=1ll*t*a/d%p,cnt++;
    			if (b==t)	return cnt;
    			d=gcd(a,p);
    		}
    		int m=sqrt(p)+1,sum=b;
    		for (int i=0;i<=m;i++)	mp[sum]=i,sum=1ll*sum*a%p;
    		int tmp=mlt(a,m,p); sum=t;
    		for (int i=1;i<=m;i++){
    			sum=1ll*sum*tmp%p;
    			if (mp[sum])	return i*m-mp[sum]+cnt;
    		}
    		return -1;
    	}
    	void main(int T){
    		for (int i=1;i<=T;i++){
    			mp.clear();
    			int a=read(),b=read(),p=read();
    			int Ans=work(a,b,p);
    			printf(Ans==-1?"Orz, I cannot find x!
    ":"%d
    ",Ans);
    		}
    	}
    };
    int main(){
    	int T=read(),type=read();
    	if (type==1)	quick_mod::main(T);
    	if (type==2)	exgcd_solve::main(T);
    	if (type==3)	BSGS_solve::main(T);
    	return 0;
    }
    
  • 相关阅读:
    leetcode231 2的幂 leetcode342 4的幂 leetcode326 3的幂
    leetcode300. Longest Increasing Subsequence 最长递增子序列 、674. Longest Continuous Increasing Subsequence
    leetcode64. Minimum Path Sum
    leetcode 20 括号匹配
    算法题待做
    leetcode 121. Best Time to Buy and Sell Stock 、122.Best Time to Buy and Sell Stock II 、309. Best Time to Buy and Sell Stock with Cooldown 、714. Best Time to Buy and Sell Stock with Transaction Fee
    rand7生成rand10,rand1生成rand6,rand2生成rand5(包含了rand2生成rand3)
    依图
    leetcode 1.Two Sum 、167. Two Sum II
    从分类,排序,top-k多个方面对推荐算法稳定性的评价
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/9519670.html
Copyright © 2011-2022 走看看