你被要求设计一个计算器完成以下三项任务:
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)的最小非负整数。
标签:完全 next 欧拉定理 逗号 str 最小 map sdoi long
Time Limit: 10 Sec Memory Limit: 512 MB
输入包含多组数据。
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <vector> #include <cstring> #include <queue> #include <complex> #include <stack> #include <cmath> #define LL long long int #define dob double using namespace std; const int N = 1000010; struct Node{int to,val,next;}E[N]; int n,type,head[N],tot; int gi() { int x=0,res=1;char ch=getchar(); while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)res*=-1;ch=getchar();} while(ch<=‘9‘&&ch>=‘0‘)x=x*10+ch-48,ch=getchar(); return x*res; } inline int QPow(int d,int z,int Mod){ int ans=1; for(;z;z>>=1,d=1ll*d*d%Mod) if(z&1)ans=1ll*ans*d%Mod; return (ans+Mod)%Mod; } inline void link(int u,int v,int w){ E[++tot]=(Node){v,w,head[u]}; head[u]=tot; } inline void work1(){ while(n--){ int y=gi(),z=gi(),p=gi(); printf("%d\n",QPow(y%p,z%(p-1),p)); } return; } inline void work2(){ while(n--){ int y=gi(),z=gi(),p=gi(); y%=p;z%=p; if(!y && z){ printf("Orz, I cannot find x!\n"); continue; } int x=QPow(y,p-2,p); x=1ll*x*z%p; printf("%d\n",x); } return; } inline void work3(){ while(n--){ int y=gi(),z=gi(),p=gi(); y%=p;z%=p; if(!y && z){ printf("Orz, I cannot find x!\n"); continue; } int m=sqrt(p),flag=0; memset(head,0,sizeof(head));tot=0; for(int i=0,d=1;i<m;++i){ link(d%N,d,i); d=1ll*d*y%p; } for(int i=1;i<=m && !flag;++i){ int ny=QPow(y,i*m,p); int x=QPow(z,p-2,p); x=1ll*x*ny%p; for(int e=head[x%N];e;e=E[e].next) if(E[e].to==x){ printf("%d\n",(i*m-E[e].val)%p); flag=1;break; } } if(!flag) printf("Orz, I cannot find x!\n"); } } int main() { n=gi();type=gi(); if(type==1)work1(); if(type==2)work2(); if(type==3)work3(); /*fclose(stdin); fclose(stdout);*/ return 0; }
标签:完全 next 欧拉定理 逗号 str 最小 map sdoi long
原文地址:http://www.cnblogs.com/fenghaoran/p/7261260.html