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. (1≤n,p≤1018)

Output

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

Sample Input

2 233

3 5

Sample Output

2

1

 

 

題意:給你一個n,讓你求n個數組成前i個是單調遞增,後n-i個是單調遞減,或者是前i個是單調遞減,後n-i個是單調遞增

答案對p取餘。

解題思路:我們以n==4爲例子

前i個是單調遞減,後n-i個是單調遞增

1 2 3 4

2 1 3 4

3 1 2 4

4 1 2 3

3 2 1 4

4 2 1 3

4 3 1 2

4 3 2 1

前i個是單調遞增,後n-i個是單調遞減

4 3 2 1

1 4 3 2

2 4 3 1

3 4 2 1

1 2 4 3

1 3 4 2

2 3 4 1

1 2 3 4

 

我們可以看到有兩項是重複出現的,所以答案爲2*2^(n-1)-2===2^n-2

這題用高精度的快速冪加速一下就行了

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=1010;
#define ll long long
ll n,m;
ll mul(ll a,ll b,ll c){
	ll ret=0,temp=a%c;
	while(b){
		if(b&1){
			ret+=temp;
			if(ret>=c) ret-=c;
		}
		temp<<=1;
		if(temp>=c) temp-=c;
		b>>=1;
	}
	return ret;
}
ll quick(ll a,ll b,ll mod){
	ll ret=1;
	while(b){
		if(b&1) ret=mul(ret,a,mod);
		a=mul(a,a,mod);
		b>>=1;
	}
	return ret;
}
int main(){
	int i,j;
	while(scanf("%lld%lld",&n,&m)!=EOF){
		ll ans=quick(2,n,m);
		printf("%lld\n",(ans-2+m)%m);
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章