1. 程式人生 > >Codeforces 992C(數學)

Codeforces 992C(數學)

傳送門

題面:

C. Nastya and a Wardrobetime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard output

Nastya received a gift on New Year — a magic wardrobe. It is magic because in the end of each month the number of dresses in it doubles (i.e. the number of dresses becomes twice as large as it is in the beginning of the month).

Unfortunately, right after the doubling the wardrobe eats one of the dresses (if any) with the 50% probability. It happens every month except the last one in the year.

Nastya owns x dresses now, so she became interested in the expected number of dresses she will have in one year. Nastya lives in Byteland, so the year lasts for k

 + 1 months.

Nastya is really busy, so she wants you to solve this problem. You are the programmer, after all. Also, you should find the answer modulo 109 + 7, because it is easy to see that it is always integer.

Input

The only line contains two integers x and k (0 ≤ x, k ≤ 1018), where x is the initial number of dresses and k

 + 1 is the number of months in a year in Byteland.

Output

In the only line print a single integer — the expected number of dresses Nastya will own one year later modulo 109 + 7.

ExamplesinputCopy
2 0
outputCopy
4
inputCopy
2 1
outputCopy
7
inputCopy
3 2
outputCopy
21
Note

In the first example a year consists on only one month, so the wardrobe does not eat dresses at all.

In the second example after the first month there are 3 dresses with 50% probability and 4 dresses with 50% probability. Thus, in the end of the year there are 6 dresses with 50% probability and 8 dresses with 50% probability. This way the answer for this test is (6 + 8) / 2 = 7.

題目描述:

    你擁有x個衣服,每個月這些衣服都會增加一倍,除了第k個月,其他月份均有50%的機率使得衣服的數量減少,問你在這k個月中,你獲得衣服的數量的期望。

題目分析:

    我們可以發現,衣服遞增(增加兩倍以及增加兩倍再-1)的數量之間是可以構成一個二叉樹結構的。

    我們假設x=1的情況,我們可以得出以下這個圖形:

    

    緊接著,我們可以發現,第k個月的時候,累計出來的最終的數最大數為,且一共有個數滿足條件,並且這個數是首項為,公差為-2的等差數列。

    如下圖:

    

    而當x!=1的時候,剩餘的數仍然是滿足上述的這些性質,只不過我們需要在首項再乘上一個x,使得其變成首項為,公差為-2的等差數列。

    此時我們對這個數列用等差數列的公式運算可得:

    =

    同時我們發現,因為每過一個月,就會有50%的機率發生發叉,因此,對於第k個月,我們的結果Sn需要再乘上

    因此經過化簡後的結果即為:

    而因為我們所需要的結果是要mod上1e9+7的數,因此,對於所求的公式,我們也需要進行一些防止為0的措施,即公式為:

    

    最後只需要帶入快速冪計算即可。

程式碼:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll powmod(ll a,ll n){
    int res=1;
    while(n){
        if(n&1){
            res=res*a%mod;
        }
        a=a*a%mod;
        n>>=1;
    }
    return res;
}
int main()
{
    ll x,k;
    cin>>x>>k;
    if(x==0){
        puts("0");
        return 0;
    }
    cout<<(x%mod*powmod(2,k+1)%mod-powmod(2,k)+1+mod)%mod<<endl;
    return 0;
}