Codeforces 696C. PLEASE(快速幂+费马小定理)

题目链接

题目大意

三个杯子,硬币一开始在中间的杯子里,每次操作可能是左边和中间或右边和中间交换,问n次操作后,硬币在中间的概率

思路

f(n) 是n次操作后硬币在中间的概率,则很明显, f(n)=1f(n1)2
展开化简得到可以得到 anbn 的形式 易得 bn=2n1

 an=2n1+132n113n,n

显然 2n1+1 2n1 互质,所以不用约分了,幂的操作可以用快速幂来处理,再用费马小定理转除为乘,这题就搞定了


PS:代码给了CPP和Python两个版本的。
PS2:原生的Python比较慢,PyPy快一点,CF上交PyPy就可以过,python大法好,自己处理大数,pow自带取模~~

代码

CPP

#include <cstdio>
#include <iostream>
using namespace std;
const int maxn = 1e5+10;
const int mod = 1e9+7;
typedef long long ll;
ll num;
ll Qpow(ll a,ll b){
    ll res = 1;
    while(b){
        if(b&1) res = res * a %mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

int main (){
    int n;
    cin >>n;
    ll b = 2;
    ll flag = -1;
    for(int i = 0 ; i < n ; i ++){
        scanf("%I64d",&num);
        b = Qpow(b,num);
        if(num %2 == 0) flag = 1;
    }
    b = b*Qpow(2LL,mod-2)%mod; // b = 2^n-1
    ll a = (b+flag+mod)%mod*Qpow(3LL,mod-2)%mod; //a = (2^n-1 -/+ 1) / 3
    printf("%I64d/%I64d",a,b);
    return 0;
}

Python

from functools import reduce
mod = 1000000007
n = input()
num = list(map(int,input().split()))
flag = 1 if len(list(filter(lambda x: x%2 == 0,num))) else -1
b = reduce(lambda x,y:pow(x,y,mod),num,2)
b = b*pow(2,mod-2,mod)%mod # b = 2^n-1
a = (b+flag)*pow(3,mod-2,mod)%mod #a = (2^n-1 -/+ 1) / 3
print("%d/%d"%(a,b))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值