bzoj 1965   //1965:[Ahoi2005] SHUFFLE 洗牌

更多题解,详见https://blog.csdn.net/mrcrack/article/details/90228694BZOJ刷题记录

方法一:乘法逆元+快速幂+快速乘

33ms / 776.00KB / 476B C++

//1965:[Ahoi2005] SHUFFLE 洗牌
//在线测评地址https://www.luogu.org/problem/P2054
//此文https://www.cnblogs.com/chenxiaoran666/p/BZOJ1965.html思路写得不错,摘抄如下:

bzoj 1965 //1965:[Ahoi2005] SHUFFLE 洗牌

作个解释:2019-10-22 20:37

移动第1次后的位置为2x%(n+1)

移动第2次后的位置为2*(2x%(n+1))%(n+1)=x*2^2%(n+1)

移动第3次后的位置为2*(x*2^2%(n+1))%(n+1)=x*2^3%(n+1)

......

移动第m次后的位置为x*2^m%(n+1)
//此文https://blog.csdn.net/Fsss_7/article/details/50648297思路不错,摘抄如下:
/*
一个置换的题。。我们对样例进行简单的分析可知经过一次变换有(1->2,2->4,3->6,4->1,5->3,6->5),然后我们就能发现p[a]=a*2%(n+1)。。然后我们设答案为X即X=p[l],所以有X*(2^m)=l%(n+1)并且2模n+1的逆元为n/2+1,所以我们将等式变换一下就有X=l*(n/2+1)^m%(n+1),然后就只要用快速幂处理这个式子就行了,同时要注意数据是10^10可能乘爆,用快速乘即可。
解释一下:n+1为奇数,2*(n/2+1)=1%(n+1)故2^m*(n/2+1)^m=1%(n+1),(n/2+1)^m为2^m关于模(n+1)的乘法逆元。
*/
//因0<N≤10^10 ,0 ≤M≤10^10,乘法long long要溢出,故采用快速乘。
//样例通过,提交AC.2019-10-22 21:33
#include <stdio.h>
#define LL long long
LL n,m,L;
LL quick_mul(LL a,LL b){//5*7 b=7 ans=5 a=10;b=3 ans=15 a=20;b=1 ans=35 a=40;b=0
    LL ans=0;
    while(b){
        if(b&1)ans=(ans+a)%(n+1);
        a=(a+a)%(n+1);
        b>>=1;
    }
    return ans;
}
LL quick_pow(LL a,LL b){
    LL ans=1;
    while(b){
        if(b&1)ans=quick_mul(ans,a);
        a=quick_mul(a,a);
        b>>=1;
    }
    return ans;
}
int main(){
    scanf("%lld%lld%lld",&n,&m,&L);
    printf("%lld\n",quick_mul(L,quick_pow(n/2+1,m)));
    return 0;
}

方法二:扩展欧几里得算法+快速幂+快速乘

 

方法三:打表找规律

相关文章:

  • 2022-01-02
  • 2021-12-25
  • 2021-06-11
  • 2021-06-08
  • 2021-10-30
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-10-28
  • 2021-11-10
  • 2021-08-27
  • 2021-10-15
  • 2021-10-01
  • 2021-05-23
  • 2022-12-23
相关资源
相似解决方案