CodeForces - 697E 找递推、快速幂

http://codeforces.com/problemset/problem/697/E
E. PLEASE
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
As we all know Barney’s job is “PLEASE” and he has not much to do at work. That’s why he started playing “cups and key”. In this game there are three identical cups arranged in a line from left to right. Initially key to Barney’s heart is under the middle cup.

Then at one turn Barney swaps the cup in the middle with any of other two cups randomly (he choses each with equal probability), so the chosen cup becomes the middle one. Game lasts n turns and Barney independently choses a cup to swap with the middle one within each turn, and the key always remains in the cup it was at the start.

After n-th turn Barney asks a girl to guess which cup contains the key. The girl points to the middle one but Barney was distracted while making turns and doesn’t know if the key is under the middle cup. That’s why he asked you to tell him the probability that girl guessed right.

Number n of game turns can be extremely large, that’s why Barney did not give it to you. Instead he gave you an array a1, a2, …, ak such that

in other words, n is multiplication of all elements of the given array.

Because of precision difficulties, Barney asked you to tell him the answer as an irreducible fraction. In other words you need to find it as a fraction p / q such that , where is the greatest common divisor. Since p and q can be extremely large, you only need to find the remainders of dividing each of them by 109 + 7.

Please note that we want of p and q to be 1, not of their remainders after dividing by 109 + 7.

Input
The first line of input contains a single integer k (1 ≤ k ≤ 105) — the number of elements in array Barney gave you.

The second line contains k integers a1, a2, …, ak (1 ≤ ai ≤ 1018) — the elements of the array.

Output
In the only line of output print a single string x / y where x is the remainder of dividing p by 109 + 7 and y is the remainder of dividing q by 109 + 7.

Examples
inputCopy
1
2
output
1/2
inputCopy
3
1 1 1
output
0/1

题意

有三个杯子都倒放在桌面上,中间的杯子里有筛子,每一次都把中间的杯子与左右两边的杯子等概论交换,问交换多次后,筛子还在中间的杯子里的概率,结果输出一个分式

思路

我们设 f(n)g(n)h(n) 分别为交换过n次后,筛子在左、中、右杯子的概率, f(0)=0g(0)=1h(0)=0
我们可以容易发现: h(n)=f(n)
左边杯子有筛子的这个事件的概率由上一次交换后左边杯子有筛子的概率的一半加上上一次中间杯子有筛子的概率的一半,也就是说:
f(i)=12(f(i1)+g(i1))
相似的原因,我们也可以得到:
g(i)=12(f(i1)+h(i1))=f(i1)
所以 g(i+1)=12(g(i)+g(i1))
这个递推方程,我们可以解得一个通项:
g(i)=2n1+(1)n32n1 ,结果是要对1e9+7取模,而且特别强调了要在取模前约分
我们可以研究一下这个分式, 2n1 2n1+(1)n 是肯定没法约分的,所以关键问题在于这个3上,而惊喜地发现 2n1+(1)n 是可以整除3的,所以我们完全可以写成:
g(i)=2n1+(1)n32n1=(2n1+(1)n)inv(3)2n1
就是这个题由于次幂很大,所以用费马小定理降幂

代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
const int mod=1e9+7;
const int mod1=mod-1;
LL quickmod(LL a,LL b,LL m)
{
    LL ans=1;
    a=a%m;
    while(b)
    {
        if(b&1)
            ans=ans*a%m;
        b>>=1;
        a=a*a%m;
    }
    return ans;
}
int main()
{
    int n;
    scanf("%d",&n);
    LL s=1;
    LL oe=1;
    for(int i=0;i<n;i++)
    {
        LL a;
        scanf("%lld",&a);
        a=a%mod1;
        oe=oe*a%2;
        s=s*a%mod1;
    }
    s=s%mod1+mod1;
    LL inv3=quickmod(3,mod-2,mod);
    LL p,q;
    q=quickmod(2,s-1,mod);
    if(oe==1) p=q-1;
    else p=q+1;
    p=p%mod;
    p=p*inv3%mod;
    printf("%lld/%lld\n",p,q);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值