zoukankan      html  css  js  c++  java
  • 题解luoguP2054 BZOJ1965【[AHOI2005]洗牌】

    我一开始理解的意思:第L张扑克牌的牌面大小是多少

    
    这是题目要我们求得,然后我看成了原序列中第L张扑克牌的位置...然后兴冲冲地找到了规律,比较有趣: $pos equiv (L*2^m) mod (n+1)$,具体怎么证我不会,可惜数竞大佬都去集训了,现在也没办法。
    
    然后按这个规律交了一发只有10分,才发现看错题了。我们要求的是m次洗牌后第L张扑克牌的牌面大小,然而刚刚我们已经发现了$pos equiv (L*2^m) pmod {n+1}$
    
    于是我们设位于L位,即现在位置(pos)在L上的牌在原序列第x张,根据上面规律:$(x*2^m) equiv L pmod {n+1}$ 
    
    所以 $x equiv L*{2^m}^{-1} pmod {n+1} $,求出$2^m$在模$(n+1)$意义下的逆元即可。
    
    - 其他:
    
    这里不用$(n+1)$不一定是质数,所以最好不要用费马小定理求,否则你只有40分,然后我们就只能用拓欧了
    
    同时我发现当m满足$2^m equiv 1 pmod {n+1}$时,恰好变成最开始的序列,然而我还是不会证明
    
    
    - 代码:
    
    

    include

    include

    include

    include

    include

    include

    define ll long long

    using namespace std;
    ll quick_pow(int a,int b,int c)//a^b%c
    {
    if(b0)return 1;
    ll x=quick_pow(a,b>>1,c);
    x=xx%c;
    if(b&1)x=x
    a%c;
    return x;
    }
    void ex_gcd(ll a, ll b, ll &x, ll &y, ll &d){
    if (!b) {d=a,x=1,y=0;}
    else{
    ex_gcd(b,a%b,y,x,d);
    y=y-x*(a/b);
    }
    return ;
    }
    ll inv(ll t, ll p){
    ll d,x,y;
    ex_gcd(t,p,x,y,d);
    return (x%p+p)%p;
    }
    int main(){
    ll n,m,l;
    cin>>n>>m>>l;
    ll p=quick_pow(2,m,n+1);
    if(p%(n+1)
    1){
    printf("%lld",l);
    }
    else{
    printf("%lld ",(l*inv(p,n+1))%(n+1));
    }
    return 0;
    }

  • 相关阅读:
    struts-OGNL
    Linux开发环境配置大全
    Mybartis逆向工程
    开发环境配置大全
    金三银四,你的专属复习宝典
    Java5~11新特性
    Struts2+Spring+Hibernate整合开发(Maven多模块搭建)
    三层架构,Struts2,SpringMVC实现原理图
    Springmvc+Spring+Mybatis整合开发(架构搭建)
    MyBatis面试题整理
  • 原文地址:https://www.cnblogs.com/Rye-Catcher/p/8991133.html
Copyright © 2011-2022 走看看