hdu_5187_zhx's contest

Problem Description
As one of the most powerful brushes, zhx is required to give his juniors n problems.
zhx thinks the ith problem's difficulty is i. He wants to arrange these problems in a beautiful way.
zhx defines a sequence {ai} beautiful if there is an i that matches two rules below:
1: a1..ai are monotone decreasing or monotone increasing.
2: ai..an are monotone decreasing or monotone increasing.
He wants you to tell him that how many permutations of problems are there if the sequence of the problems' difficulty is beautiful.
zhx knows that the answer may be very huge, and you only need to tell him the answer module p.
 

 

Input
Multiply test cases(less than 1000). Seek EOF as the end of the file.
For each case, there are two integers n and p separated by a space in a line. (1n,p1018)
 

 

Output
For each test case, output a single line indicating the answer.
 

 

Sample Input
2 233 3 5
 

 

Sample Output
2 1
Hint
In the first case, both sequence {1, 2} and {2, 1} are legal. In the second case, sequence {1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1} are legal, so the answer is 6 mod 5 = 1
 
看了網上大神的思路:
轉自:http://blog.csdn.net/qingshui23/article/details/61627248
 
首先咱們將題目給定的條件在細化一下:
(1)a1..ai是單調遞增的,那麼ai..an必定是單調遞減的,並且 ai=n
(2)a1..ai是單調遞減的,那麼ai..an必定是單調遞增的,並且 ai=1
將條件細化成這樣以後就好想多了,其實 (1)(2) 是沒有什麼區別的,就拿第一個來講,由於 ai=n 這是肯定的,因此只須要肯定 i 的位置就行啦,肯定好 i 的位置以後,剩下的就是簡單的組合數學了,假設 n=5,那麼 i 的位置有 5 個,刨除掉 1,還有 4 個數
i=1C04
i=2C14
i=3C24
i=4C34
i=5C44
因此總數是 24 根據二項式定理,那麼知足第 (2) 個條件的也有 24 個,可是中間有重複的,就是單調遞增的和單調遞減的多算了以此,因此減 2,總數就是 2422
能夠推出這個題的總的方法數就是 2n122, 即 2n2,還須要注意的問題就是,這個取模的數太大,因此在進行快速冪的時候不要直接乘,要進行快速乘法。
i=1與i=n的遞增與遞減,計算了兩遍。
 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define maxn 100005
ll mul(ll a,ll b,ll m)
{
    ll res=0;
    while(b)
    {
        if(b&1) res+=a;
        if(res>m) res-=m;
        a+=a;
        if(a>m)
        a-=m;
        b>>=1;
    }
    return res;
}
ll pow(ll a,ll b,ll m)
{
    ll res=1;
    while(b)
    {
        if(b&1) res=mul(res,a,m);
        a=mul(a,a,m);
        b>>=1;
    }
    return res;
}

int main()
{
    ll n,p;

    while(~scanf("%lld%lld",&n,&p))
    {
        if(n==1&&p!=1)
            {puts("1");continue;}
        else if(n==1&&p==1)
            {puts("0");continue;}
        ll ans=pow(2,n,p)-2;
        ans%=p;
        ans=(ans+p)%p;
        printf("%lld\n",ans);
    }
    return 0;
}
相關文章
相關標籤/搜索