Clever Y [Bzoj 1467]
2016-06-17 18:10
351 查看
题目地址请点击——
但是如果给出 X、Z、K,你是否知道如何快速的计算 Y 呢?
2 4 3
0 0 0
No Solution
Clever Y
Description
小Y发现,数学中有一个很有趣的式子: XY mod Z = K 给出 X、Y、Z,我们都知道如何很快的计算 K。但是如果给出 X、Z、K,你是否知道如何快速的计算 Y 呢?
Input
本题由多组数据(不超过20组),每组测试数据包含一行三个整数 X、Z、K(0≤X,Z,K≤109)。 输入文件一行由三个空格隔开的 0 结尾。Output
对于每组数据:如果无解则输出一行 No Solution,否则输出一行一个整数 Y(0≤Y<Z),使得其满足 XY mod Z = K,如果有多个解输出最小的一个 Y。Sample Input
5 58 332 4 3
0 0 0
Sample Output
9No Solution
Solution
扩展 Baby-Step-Giant-Step 模板题。Code
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #define LL long long #define HASH_MOD 786433 using namespace std; LL x,z,k,cnt=0,xxx,yyy,ans; LL ex_gcd(LL x,LL y,LL &a,LL &b){ if(y==0){a=1;b=0;return x;} LL fa,fb; LL c=ex_gcd(y,x%y,fa,fb); a=fb; b=fa-fb*(x/y); return c; } struct map{ LL h[800000],v[800000],nxt[800000],ne[800000]; void clear(){ memset(nxt,-1,sizeof nxt); memset(h,-1,sizeof h); ne[786433]=0; for(LL i=0;i<786433;i++)ne[i]=i; } LL fi(LL x){ LL tmp=x,pre; while(tmp!=ne[tmp])tmp=ne[tmp]; while(x!=tmp){pre=ne[x];ne[x]=tmp;x=pre;} return tmp; } void insert(LL x,LL y){ LL mx=x%HASH_MOD; while(nxt[mx]!=-1) mx=nxt[mx]; nxt[mx]=fi(0); ne[nxt[mx]]=ne[nxt[mx]]+1; h[nxt[mx]]=x; v[nxt[mx]]=y; } LL find(LL x){ LL mx=x%HASH_MOD; while(x!=h[mx]&&nxt[mx]!=-1)mx=nxt[mx]; if(x!=h[mx])return -1; return v[mx]; } }; map hash; int main(){ while(scanf("%lld%lld%lld",&x,&z,&k)!=EOF&&(x||z||k)){ hash.clear(); LL gg=ex_gcd(x,z,xxx,yyy),d=1,MAXN,tmp,tmp2,tt; while(gg!=1){ if(k%gg!=0){printf("No Solution\n");goto nxt;} k/=gg;z/=gg;d*=x/gg; cnt++; gg=ex_gcd(x,z,xxx,yyy); } x%=z;k%=z; MAXN=ceil(sqrt((double)z)),tmp=1; if(k==d%z){printf("0\n");goto nxt;} hash.insert(1,0); for(LL i=1;i<MAXN;i++){ tmp=tmp*x%z; if(d*tmp%z==k){ if(i<=cnt){printf("%lld\n",i);goto nxt;} else{printf("%lld\n",i+cnt);goto nxt;} } hash.insert(tmp,i); } tmp2=tmp,tt=tmp*x%z; for(LL i=MAXN;i<=cnt;i++){ tmp2=tmp2*x%z; if(d*tmp%z==k){printf("%lld\n",i);goto nxt;} } tmp=tt; if(d*tmp%z==k){ if(MAXN<=cnt){printf("%lld\n",MAXN);goto nxt;} else{printf("%lld\n",MAXN+cnt);goto nxt;} } ex_gcd(d*tmp,z,xxx,yyy); xxx=(xxx*k%z+z)%z; if((ans=hash.find(xxx))!=-1){printf("%lld\n",ans+MAXN+cnt);goto nxt;} for(LL i=2;i<=MAXN;i++){ tmp=tmp*tt%z; ex_gcd(d*tmp,z,xxx,yyy); xxx=(xxx*k%z+z)%z; if((ans=hash.find(xxx))!=-1){printf("%lld\n",ans+MAXN*i+cnt);goto nxt;} } printf("No Solution\n"); nxt:; } return 0; }
相关文章推荐
- 飛飛(七十四)阅读 STL中的简单容器和迭代器
- memset效率问题
- TCP/IP 封装-分用
- 基于bootstrap风格的项目
- Android studio 和 Eclipse在Win上常见快捷键对比
- Xdebug文档(六) 分析PHP脚本
- android 设置跳转
- 纯代码实现 AutoLayout
- find命令的使用
- Socket与SocketServer结合多线程实现多客户端与服务器通信
- python IDLE 背景以及字体的修改
- 【solr】关于solr schema.xml 和solrconfig.xml的解释
- 把玩之python爬虫正则表达式
- Lock wait timeout exceeded; try restarting transaction
- struts.xml(package包)
- Codis FE管理界面验证配置
- day04脚本练习题
- flume常用属性的说明
- JSP页面嵌套c:forEach
- C++ Macro