这题到现在还是只有我一个人过?太冷门了吧,毕竟你谷上很少有人会去做往年ACM比赛的题

题面意思很简单,每次给出\(K_1\),让你求一个\(K_2\)满足\(K_1^{K_2}\equiv K_2(\mod 10^{12})\)

题目乍一看很有数学风格,看到取模和幂次想到什么?

费马大小定理,BSGS,二次探测?,不过在这里好像都用不了啊。

所以我们先考虑一个最朴素的想法:爆搜,每次直接枚举每一位上放什么数字,然后快速幂判断。

这样肯定T飞啊,所以我们进行一个大力观察,我们手玩下第二个样例:

\[99^9\equiv 9(\mod 10^{1});99^9\equiv 99(\mod 10^{2})
\]

\[99^{99}\equiv 99(\mod 10^{2});99^{99}\equiv 899(\mod 10^{3})
\]

\[99^{899}\equiv 899(\mod 10^{3});99^{899}\equiv 9899(\mod 10^{4})
\]

\(\dots\)

发现什么没,若\(K_1^{n}\equiv dn(\mod 10^{\operatorname{bit}_n+1})\),那么\(K_1^{dn}\equiv dn(\mod 10^{\operatorname{bit}_{dn}})\)!(上面的\(dn\)表示在\(n\)前面放一个\(d\))

这个规律的提出在大刘的蓝书上也有涉及,并且可以用归纳法证明之,这里不再赘述。

所以接下来的流程就出来了,我们对于每一位,如果可以用这个规律刷出下一位就直接跳,否则(就是用规律算出前导零的情况)再枚举这一位的取值。

实际应用下在这个trick的优化下,再加上玄学的\(O(1)\)快速乘,可以跑的非常快(\(200ms\)过了\(1600\)组数据)。

CODE

#include<cstdio>
#define RI register int
typedef long long LL;
const LL lim=1e11,R=(1LL<<20)-1; int n,cases;
LL quick_mul(LL x, LL y, LL mod)
{
return (x *(y>>20)%mod*(1LL<<20)%mod+x*(y&(R))%mod)%mod;
}
inline LL quick_pow(LL x,LL p,LL mod,LL mul=1)
{
for (;p;p>>=1,x=quick_mul(x,x,mod)) if (p&1) mul=quick_mul(mul,x,mod); return mul;
}
inline bool expand(int idx,LL n,LL p,LL mod)
{
int t; LL nxt; while (idx<12) if ((nxt=quick_pow(n,p,10LL*mod))!=p) p=nxt,++idx,mod*=10LL; else break;
if (idx==12&&quick_pow(n,p,mod)==p) return printf("%lld\n",p),1; return 0;
}
inline bool DFS(int idx,LL p,LL mod)
{
if (idx==12) { if (p>=lim&&quick_pow(n,p,mod)==p) return printf("%lld\n",p),1; return 0; }
if (quick_pow(n,p,mod)==p&&expand(idx,n,p,mod)) return 1;
for (RI i=0;i<10;++i) if (quick_pow(n,1LL*i*mod+p,mod)==p&&DFS(idx+1,1LL*i*mod+p,10LL*mod)) return 1; return 0;
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
while (scanf("%d",&n),n)
{
printf("Case %d: Public Key = %d Private Key = ",++cases,n);
for (RI i=0;i<10;++i) if (DFS(1,i,10)) break;
}
return 0;
}

UVA12253 简单加密法 Simple Encryption的更多相关文章

  1. uva 12253 - Simple Encryption(dfs)

    题目链接:uva 12253 - Simple Encryption 题目大意:给定K1.求一个12位的K2,使得KK21=K2%1012 解题思路:按位枚举,不且借用用高速幂取模推断结果. #inc ...

  2. 【JMeter_19】JMeter逻辑控制器__简单控制器<Simple Controller>

    简单控制器<Simple Controller> 业务逻辑: 就像他的名字一样,简单,可以理解为一个文件夹,就是分组用的,没有其他特殊功能,但相比不添加简单控制器,区别在于简单控制器可以被 ...

  3. 设计模式:简单工厂(Simple Factory)

    定义:根据提供的数据或参数返回几种可能类中的一种. 示例:实现计算器功能,要求输入两个数和运算符号,得到结果. 结构图: HTML: <html xmlns="http://www.w ...

  4. 数据结构【一】:简单队列simple queue

    简单的FIFO队列实现,非线程安全! 1.queue.h : abstract data type queue #ifndef CUR_QUEUE_H #define CUR_QUEUE_H #inc ...

  5. 简单工厂(Simple Factory),最合适的设计模式首秀.

    简单工厂又称为静态工厂方法(static factory method)模式,简单工厂是由一个工厂来决定创建出哪一种个体的实现,在很多的讨论中,简单工厂做为工厂方法模式(Factory Method) ...

  6. 使用C# (.NET Core) 实现简单工厂(Simple Factory) 和工厂方法设计模式 (Factory Method Pattern)

    本文源自深入浅出设计模式. 只不过我是使用C#/.NET Core实现的例子. 前言 当你看见new这个关键字的时候, 就应该想到它是具体的实现. 这就是一个具体的类, 为了更灵活, 我们应该使用的是 ...

  7. UVALive 4998 Simple Encryption --DFS

    题意: 给出K1,求一个12位数(不含前导0)K2,使得K1^K2 mod (10^12) = K2. 解法: 求不动点问题. 有一个性质: 如果12位数K2满足如上式子的话,那么K2%1,K2%10 ...

  8. LA 4998 Simple Encryption

    题意:输入正整数$K_1(K_1 \leq 50000)$, 找一个$12$位正整数$K_2$(不能含有前导零)使得${K_1}^{K_2}\equiv K_2(mod10^{12})$. 例如,$K ...

  9. UVALive 4998 Simple Encryption

    题目描述: 输入正整数K1(K1<=5000),找一个12位正整数K2使得K1K2=K2(mod 1012). 解题思路: 压缩映射原理:设X是一个完备的度量空间,映射ƒ:Χ→Χ 把每两点的距离 ...

随机推荐

  1. Xamarin.Forms 使用本地数据库之 SQLite

    前言 Xamarin.Forms支持使用SQLite数据库引擎.本文介绍了Xamarin.Forms应用程序如何读取和写入数据到使用SQLite.Net的本地SQLite数据库. 在Xamarin.F ...

  2. Python绘图工具Plotly的简单使用

    1.Plotly被称为史上最好的绘图工具之一,为了更好的展示金融数据的复杂性. Plotly的官方网站为:https://plot.ly/ python量化的关键是金融数据可视化,无论是传统的K线图, ...

  3. java----八种排序算法

    1.直接插入排序 经常碰到这样一类排序问题:把新的数据插入到已经排好的数据列中. 将第一个数和第二个数排序,然后构成一个有序序列 将第三个数插入进去,构成一个新的有序序列. 对第四个数.第五个数……直 ...

  4. linux hadoop2.x快速安装

    ........ http://blog.csdn.net/se7en_q/article/details/47258007

  5. MongoDB Sharding分片配置

    Ps:mongod是mongodb实例,mongos被默认为为mongodb sharding的路由实例. 本文使用的mongodb版本为3.2.9,因此参考网址为:https://docs.mong ...

  6. win7 中 sql server2005 卸载简介

    注:卸载前一定要做好备份,一定要清理干净,不然重装会出错(只针对完全卸载,没试过只删除一个版本的) 工具:①Windows Install Clean Up  ②SrvInstw.exe 1.停止所有 ...

  7. c/c++ 数组 数组的引用,指针数组的引用

    c/c++ 数组 知识点 1,数组的声明和初始化,对应代码里的test1和test2 2,char数组,对应代码里的test3 3,数组不可以拷贝和复制,对应代码里的test4 4,指针数组, 数组的 ...

  8. c/c++线性循环队列

    线性循环队列 队列是先进先出,和栈相反. 线性循环队列,牺牲一个空间,实现循环.比如空间大小为4,牺牲一个空间,所以最多放3个元素. 假设front指向0位置,tail指向3位置 1 2 3 空 出队 ...

  9. Linux学习历程——Centos 7 ps命令基础

    一.ps命令介绍 ps命令是Process Status的缩写,用于查看系统进程状态,ps命令输出值非常多,通常结合管道符使用. 二.实例 1.我们直接输入ps命令,不加任何参数. 可以看到默认输出4 ...

  10. [Hive_9] Hive 的排序

    0. 说明 全排序(order by) | 部分排序(sort by) | hash 分区(distribute by)  | cluster by 1. 前期准备 1.1 建表 create tab ...