zoukankan      html  css  js  c++  java
  • 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 o u+1 pmod{p}).

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

    Turn (u o 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
    ",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
    ",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

  • 相关阅读:
    【类似N^N做法的斐波那契数列】【HDU1568】 Fibonacci
    【取对数+科学计数法】【HDU1060】 N^N
    【枚举+数学】【HDU1271】整数对 难度:五颗星
    【欧拉函数】【HDU1286】 找新朋友
    【筛素数表证明】【O[n]】
    【沙茶了+筛选保存最大质因数】【HDU2136】Largest prime factor
    【gcd+数学证明】【HDU1722】 CAKE
    【贪心】【HDU3177】 搬家问题
    HDU2093 字符串2种不错的读入思路
    tf.argmax()
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9762632.html
Copyright © 2011-2022 走看看