LA 4998 Simple Encryption (数论 dfs)
来源:互联网 发布:网络棋牌平台排名2017 编辑:程序博客网 时间:2024/05/29 14:42
LA 4998 Simple Encryption
题意:
输入正整数K1(K1≤50000),找一个12位正整数K2(不能含有前导零)使得K1^K2≡K2(mod10^12)。
思路:
神奇的数论题,怎么也想不出来,膜膜大佬的方法。
K1^K2≡K2(mod10^12),同时意味着:
K1^K2≡K2(mod10^i),i ≤12
现在我们用(abcd)表示一个四位数,用(bcd)表示它的后三位;
对于任意一个底数k;我们要证明如果 k^(abcd) = abcd(mod 1e4); 就有 k^(bcd) = bcd(mod 1e3);
显然 k^(abcd) = bcd (mod 1e3)
k^(abcd) = k^(a000) * k^(bcd) = bcd (mod 1e3)
并且根据欧拉函数的求法,有φ(10^i)=10^i*(1-1/2)*(1-1/5)=4*10^(i-1)
所以 φ(1e3) = 4*10^2
根据欧拉定理 k^ φ(1e3) = 1 (mod 1e3)
又因为 a000 是 φ(1e3) 的倍数; 所以 k^ (a000) = 1 (mod 1e3)
那么 k^(abcd) = k^(a000) * k^(bcd) = k^(bcd) = bcd (mod 1e3)
所以 如果 k^(abcd) = abcd(mod 1e4); 就有 k^(bcd) = bcd(mod 1e3);
同理,我们可以得到 如果 k^(abcd…) = abcd…(mod 1ei); 就有 k^(bcd…) = bcd…(mod 1ei-1);
那么我们反向思考,要去找这个12位的k2,就去找一个i位的k3满足 K1^k3≡k3(mod10^i)。
合法的k2就是在这个k3上加上一些前导。
所以就可以用dfs像数位dp这样搞啦!
#include <algorithm>#include <cstdio>#include <cstring>#include <iostream>#define LL long longusing namespace std;LL multi(LL x, LL y, LL mod){//神奇的快速乘隔开后20位单独算 LL lf = x * (y >> 20) % mod * (1ll << 20) % mod; LL rg = x * (y & ((1ll << 20) - 1)) % mod; return (lf + rg) % mod;}//首先考虑模数最大为10^12,不超过2进制中的40位,那么我们可以将待乘值拆分成高20位与低20位,//确保在乘法时始终不超过60位.LL power(LL a, LL p, LL mod){ LL ans = 1; while( p ){ if(p & 1) ans = multi(ans, a, mod); p >>= 1; a = multi(a, a, mod); } return ans % mod;}LL n;LL ans[50010];bool flag;void dfs(int pos, LL pre, LL mod){ if(pos == 12){ if(pre < 1e11 || power(n, pre, mod) != pre) return; ans[n] = pre; flag = 1; return; } for(int i=0; i<=9; i++){ LL nex = mod * i + pre;//k2 从个位开始推(加一个前导) LL lf = power(n, nex, mod);//左式 LL rg = nex % mod;//右式 if(lf != rg) continue; dfs(pos + 1, nex, mod * 10); if( flag ) return;//找到一个ans就返回 }}void solve(){ if(ans[n] != -1) return;//记忆化搜索 flag = 0; dfs(0, 0, 1);}int main(){ int kase = 0; memset(ans, -1, sizeof(ans)); while(~scanf("%lld", &n) && n){ solve(); printf("Case %d: Public Key = %lld Private Key = %lld\n", ++kase, n, ans[n]); }}
- LA 4998 Simple Encryption (数论 dfs)
- uva 12253 - Simple Encryption(dfs)
- UVA - 12253 Simple Encryption (同余)
- LA4998 Simple Encryption
- Simple MD5 encryption in Java
- LA 3942 trie树 + dfs(dp)
- LA-3521 (数论)
- hdu 5490 Simple Matrix(数论)
- 【jzoj4868】【Simple】【数论】
- HDOJ1111 Secret Code(数论+DFS)
- [BZOJ3643]Phi的反函数(数论+dfs)
- la 4794 分享巧克力 dfs(超时) dp
- UVA 1267 && LA 3902 Network (思路--树上的DFS)
- HDU 4143 A Simple Problem(数论-水题)
- HDU 5974 A Simple Math Problem (数论+解方程组)
- HDU 5974 A Simple Math Problem(数论)
- hdu 5974 A Simple Math Problem (数论思路)
- HDU-6237:A Simple Stone Game(数论)
- CentOS7安装pip
- 预编译宏
- javascript的相关格式化
- spring 整合内存缓存LoadingCache
- 基于jenkins搭建一个分布式持续集成服务器
- LA 4998 Simple Encryption (数论 dfs)
- iOS应用状态保存和恢复
- CentOS_6.5配置iptables防火墙策略
- 从业务骨干到管理精英
- 【LintCode】Max Points on a Line(笔记)
- android应用的视频压缩
- 不关闭seLinux解决vsftpd服务本地用户不能登录问题(500 OOPS: cannot change directory:/home/***)
- 查询MySql数据库物理文件存放位置
- 安卓开发实现长连接,心跳,java后端,实现消息推送,持续更新中