CF995E Number Clicker

题目描述

Allen is playing Number Clicker on his phone.

He starts with an integer u u on the screen. Every second, he can press one of 3 buttons.

Turn \(u \to u+1 \pmod{p}\).

Turn \(u \to u+p-1 \pmod{p}\).

Turn \(u \to u^{p-2} \pmod{p}\).

Allen wants to press at most 200 buttons and end up with v v on the screen. Help him!

输入输出格式

输入格式:

The first line of the input contains 3 positive integers: \(u, v, p\)( \(0 \le u, v \le p-1\) , \(3 \le p \le 10^9 + 9\) ). \(p\) is guaranteed to be prime.

输出格式:

On the first line, print a single integer \(\ell\) , the number of button presses.

On the second line, print integers \(c_1, \dots, c_\ell\), the button presses.

For \(1 \le i \le \ell\) , \(1 \le c_i \le 3\).

We can show that the answer always exists.


长见识了。

发现这道题可以建成一个比较随机的图。

根据生日攻击,我们基本上只需要图的点数\(p\)开根号个\(\sqrt p\),就可以找到答案了。

于是进行双向搜索,合并答案即可。


Code:

#include <cstdio>
#include <map>
#define ll long long
const int N=2e5;
ll u,v,p,q[N+10],l=1,r=0,s[N],tot;
std::map <ll,ll > pre,used,opt,pre0,opt0;
void in(ll now,ll to,ll op)
{
if(!used[to])
{
used[to]=1;
opt[to]=op;
pre[to]=now;
q[++r]=to;
}
}
ll quickpow(ll d,ll k)
{
ll f=1;
while(k)
{
if(k&1) f=f*d%p;
d=d*d%p;
k>>=1;
}
return f;
}
int bfs0()
{
q[++r]=u;
while(l<=r&&r<=N)
{
ll now=q[l++];
if(now==v)
{
while(now!=u) s[++tot]=opt[now],now=pre[now];
printf("%lld\n",tot);
for(int i=tot;i;i--)
printf("%lld ",s[i]);
return 1;
}
ll to=(now+1)%p;
in(now,to,1);
to=(now+p-1)%p;
in(now,to,2);
to=quickpow(now,p-2);
in(now,to,3);
}
return 0;
}
void in0(ll now,ll to,ll op)
{
if(!used[to])
{
used[to]=1;
opt0[to]=op;
pre0[to]=now;
q[++r]=to;
}
}
ll tmp;
void swap(ll &x,ll &y){tmp=x,x=y,y=tmp;}
void bfs1()
{
used.clear();
l=1,r=0;
q[++r]=v;
while(l<=r&&r<=N)
{
ll now=q[l++];
if(pre.find(now)!=pre.end())
{
ll t=now;
while(now!=u) s[++tot]=opt[now],now=pre[now];
for(int i=1;i<=tot>>1;i++) swap(s[i],s[tot+1-i]);
now=t;
while(now!=v) s[++tot]=opt0[now],now=pre0[now];
printf("%lld\n",tot);
for(int i=1;i<=tot;i++)
printf("%lld ",s[i]);
return;
}
ll to=(now+1)%p;
in0(now,to,2);
to=(now+p-1)%p;
in0(now,to,1);
to=quickpow(now,p-2);
in0(now,to,3);
}
}
int main()
{
//freopen("dew.out","w",stdout);
scanf("%lld%lld%lld",&u,&v,&p);
if(bfs0()) return 0;
bfs1();
return 0;
}

2018.10.9

CF995E Number Clicker 解题报告的更多相关文章

  1. 【LeetCode】137. Single Number II 解题报告(Python)

    [LeetCode]137. Single Number II 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/single- ...

  2. USACO Section1.5 Number Triangles 解题报告

    numtri解题报告 —— icedream61 博客园(转载请注明出处)--------------------------------------------------------------- ...

  3. LeetCode 476 Number Complement 解题报告

    题目要求 Given a positive integer, output its complement number. The complement strategy is to flip the ...

  4. Lintcode: Majority Number II 解题报告

    Majority Number II 原题链接: http://lintcode.com/en/problem/majority-number-ii/# Given an array of integ ...

  5. USACO Section 1.5 Number Triangles 解题报告

    题目 题目描述 现在有一个数字三角形,第一行有一个数字,第二行有两个数字,以此类推...,现在从第一行开始累加,每次在一个节点累加完之后,下一个节点必须是它的左下方的那个节点或者是右下方那个节点,一直 ...

  6. Winter-1-F Number Sequence 解题报告及测试数据

    Time Limit:1000MS     Memory Limit:32768KB Description ​A number sequence is defined as follows:f(1) ...

  7. CF995E Number Clicker (双向BFS)

    题目链接(洛谷) 题目大意 给定两个数 \(u\) , \(v\) .有三种操作: \(u=u+1(mod\) \(p)\) . \(u=u+p−1(mod\) \(p)\) . \(u=u^{p−2 ...

  8. 【LeetCode】264. Ugly Number II 解题报告(Java & Python)

    标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ https://leetcode.com/prob ...

  9. 【LeetCode】537. Complex Number Multiplication 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 日期 题目地址:https://leetcode.com/pr ...

随机推荐

  1. leetcode第221题(最大正方形)的本地IDE实现及变形

    问题描述: 在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积.PS:本文也对只包含0的最大正方形面积进行了运算 示例: 输入: 1 0 1 0 0 1 0 1 1 1 ...

  2. 基于centos7实现的nfs

    NFS NFS(Network FileSystem,网络文件系统),最早由Sun公司所发展出来的,主要是通过网络让不同的主机.不同的操作系统,可以彼此分享个别档案,因此我们也可以简单把NFS看成是一 ...

  3. Linux中的代码编辑器vim

    Vim的三种工作模式 命令行模式 插入模式 底行模式 Vim 的命令行模式 命令行模式是进入vim后的初始模式,在该模式下主要是使用方向键来移动光标的位置,并通过相应的命令来进行文字的编辑. 切换方法 ...

  4. LInux操作随手笔记

    一.find 的用法 实例 find / -name test.txt 就可以找到这个文件的路径(如果存在). 二.学用vi编辑器,学用rz往linux服务器上面上传文件 linux中rz 和 sz ...

  5. 1016-06-首页20-封装工具条-有控件在viewDidLoad的时候距离顶部是0--到了viewWillAppear或viewDidAppear系统就加了64

  6. Makefile (2) gdb

    gdb调试 1.用debug的方式编译 -g 2.打上断点 3.单步调试 step into 进入函数里面 step over 运行整个函数 step return 跳出当前函数 4.继续运行 5.打 ...

  7. APUE中对出错函数的封装

    // 输出至标准出错文件的出错处理函数static void err_doit(int, int, const char *, va_list); /* * Nonfatal error relate ...

  8. Educational Codeforces Round 43 E. Well played!(贪心)

    E. Well played! time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  9. POJ 2836 状压DP

    Rectangular Covering Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2727   Accepted: 7 ...

  10. POJ:2566-Bound Found(尺取变形好题)

    Bound Found Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5408 Accepted: 1735 Special J ...