CF995E Number Clicker 解题报告

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

原文地址:https://www.cnblogs.com/ppprseter/p/9762632.html

时间: 2024-11-10 04:43:04

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

hdu 1711 Number Sequence 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 题目意思:给出一条有n个数的序列a[1],a[2],......,a[n],和一条有m 个数的序列b[1],b[2],......,b[m],求出b[1],b[2],...,b[m]在序列a中完全匹配时,在序列a中的位置,如果找不到输出-1. 这几天一直在学kmp,该题算是kmp的入门题吧.有个地方要稍稍注意,代码中,主串和模式串的比较初始值为-1,-1,否则如果从0开始,会默认第一个字符是相

USACO Section1.5 Number Triangles 解题报告

numtri解题报告 —— icedream61 博客园(转载请注明出处)------------------------------------------------------------------------------------------------------------------------------------------------[题目] 有一个数字的金字塔,形状如下    7   3 8  8 1 0 2 7 4 4 4 5 2 6 5 要从顶端开始走,每次只能向

Lintcode: Majority Number II 解题报告

Majority Number II 原题链接: http://lintcode.com/en/problem/majority-number-ii/# Given an array of integers, the majority number is the number that occurs more than 1/3 of the size of the array. Find it. Note There is only one majority number in the arra

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

Time Limit:1000MS     Memory Limit:32768KB Description ?A number sequence is defined as follows:f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.Given A, B, and n, you are to calculate the value of f(n). Input The input consists of mult

LeetCode - 136. Single Number - ( c++ ) - 解题报告

1.题目大意 Given an array of integers, every element appears twice except for one. Find that single one. Note:Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 给定一个数组的整数,数组中的每个元素都出现了两次.例外地,有一个元素只出现

解题报告 之 POJ2699 The Maximum Number of Strong Kings

解题报告 之 POJ2699 The Maximum Number of Strong Kings Description A tournament can be represented by a complete graph in which each vertex denotes a player and a directed edge is from vertex x to vertex y if player x beats player y. For a player x in a t

USACO Section1.2 Name That Number 解题报告

namenum解题报告 —— icedream61 博客园(转载请注明出处)------------------------------------------------------------------------------------------------------------------------------------------------[题目] 你有一个手机,键盘如下所示: 2: A,B,C 5: J,K,L 8: T,U,V 3: D,E,F 6: M,N,O 9:

解题报告 之 POJ3057 Evacuation

解题报告 之 POJ3057 Evacuation Description Fires can be disastrous, especially when a fire breaks out in a room that is completely filled with people. Rooms usually have a couple of exits and emergency exits, but with everyone rushing out at the same time

解题报告 之 CodeForces 91B Queue

解题报告 之 CodeForces 91B Queue Description There are n walruses standing in a queue in an airport. They are numbered starting from the queue's tail: the 1-st walrus stands at the end of the queue and the n-th walrus stands at the beginning of the queue.