luogu_P2054 bzoj 1965 洗牌 题解 快速幂 快速乘

Posted ChrisK

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu_P2054 bzoj 1965 洗牌 题解 快速幂 快速乘相关的知识,希望对你有一定的参考价值。

题目链接:

  Luogu:https://www.luogu.org/problem/P2054

  bzoj:https://www.lydsy.com/JudgeOnline/problem.php?id=1965

找到规律:

  上一次在x位置,下一次就会在 x*2%(n+1) 位置

那么就是要求:

  x * (2^m) = L(mod n+1)

第一反应exgcd,但是突然感觉有点不太优秀。

因为n是偶数(题目说了)

所以2和n+1为互质

所以设 z *  2 =1(mod n+1)

  z就为2在mod n+1下的逆元

  z *  2 +(n+1)*y = 1

当 y=-1 时得出 z 最小为 n/2+1

所以 x=(n/2+1)^ m *L (mod n+1)

用一个快速幂和一个快速乘就可以切了。

不用快速乘中间会爆成负数。

代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=1e10+10;
ll n,m,l;
inline ll qm(ll x,ll y){
    ll mod=(n+1),ans=0;
    x%=mod;
    while(y){
        if(y&1) ans=(ans+x)%mod;
        x=(x+x)%mod;
        y>>=1;
    }
    return ans%mod;
}
inline ll qp(ll x,ll y){
    ll mod=(n+1),ans=1;
    x%=mod;
    while(y){
        if(y&1) ans=qm(ans,x)%mod;
        x=qm(x,x)%mod;
        y>>=1;
    }
    return ans%mod;
}
int main()
{
    scanf("%lld%lld%lld",&n,&m,&l);
    ll ans=qp(n/2+1,m);
    ans=qm(ans,l);
    printf("%lld\n",ans);
    //system("pause");
    return 0;
}

 

以上是关于luogu_P2054 bzoj 1965 洗牌 题解 快速幂 快速乘的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1965 [Ahoi2005]洗牌

BZOJ 1965 [AHOI2005]洗牌

bzoj 1965 [Ahoi2005]SHUFFLE 洗牌 数学

bzoj1965[Ahoi2005]SHUFFLE 洗牌 - 快速幂

bzoj1965 [Ahoi2005]SHUFFLE 洗牌 欧拉定理

[luogu P2054] [AHOI2005]洗牌