BestCoder Round #33——1002——zhx's contest

问题描述
作为史上最强的刷子之一,zhx的老师让他给学弟(mei)们出n道题。 zhx认为第i道题的难度就是i。他想要让这些题目排列起来很漂亮。 zhx认为一个漂亮的序列{ai}下列两个条件均需满足。 1:a1..ai是单调递减或者单调递增的。 2:ai..an是单调递减或者单调递增的。 他想你告诉他有多少种排列是漂亮的。 因为答案很大,所以只需要输出答案模p之后的值。
输入描述
多组数据(不多于1000组)。读到文件尾。 每组数据包含一行两个整数np。(1n,p1018
输出描述
每组数据输出一行一个非负整数表示答案。
输入样例
2 233

3 5
输出样例
2

1
Hint
第一组数据中{1, 2}和{2, 1}合法。

第二组数据中{1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}都合法,所以答案是6 mod 5 = 1。

 大意:先用数学公式得出2的n次-2(ai肯定为最小或者最大,那么其他数就放在他的左边或者右边,因为一旦放下顺序就确定了所以n-1个数排列就是2的n-1次,再乘以二减去重复的两个全顺排和全逆排就是答案,用快速幂求出答案,不然溢出,快速幂由快速乘法得到,快速乘法又加法得到。

算是模板题目,a&1是指取a二进制的末位 >>1是指向右移一位

#include<iostream>

#include<cstring>

#include<algorithm>

#include<cmath>

#include<cstdio>

using namespace std;

typedef long long ll;

ll mod;

ll mul(ll a, ll b)

{

    ll ans = 0;

    while(b){

        if(b&1)

          ans = (ans+a)%mod;

        a = (a+a)%mod;

        b >>= 1;

    }

    return ans;

}

ll pow(ll a, ll b)

{

    ll ans = 1;

    while(b){

        if(b&1)

          ans = mul(ans,a);

       a = mul(a, a);

       b >>= 1;

    }

    return ans;

}

int main()

{

    ll n;

    while(~scanf("%lld%lld",&n,&mod))

    {

        if(n == 1)

            printf("%lld\n",n%mod);

        else printf("%lld\n",((pow(2ll,n)-2)+mod)%mod);

    }

    return 0;

}
View Code

 

你可能感兴趣的:(round)