【codechef】Zombinatorial(找规律)

You are given a function f which is defined as :

Your task is to find the value of

 
where M is given in input.

Input Format

First line contains T, the number of test cases.

First line of each test case contain 3 space separated integers NM and Q.

Next Q line follows, each line contain r.

Output Format

For each test case, output Q lines, each line containing the required answer.

Constraints

2 ≤ N ≤ 106

1 ≤ M ≤ 109

2 ≤ Sum of N over all test cases ≤ 106

1 ≤ Sum of Q over all test cases ≤ 2*105

1 ≤ T ≤ 105

1 < r < N

Sample Input
2
5 114 1
2
50 3874 3
31
17
21

Sample Output
72
3718
624
1144

Explanation for first test case

f[1] = 1

f[2] = 2

f[3] = 1*22 * 3 = 12

f[4] =1*23*32*4 = 8*9*4 = 288

f[5] = 1*24*33*42*5 =34560

value of f[5] / (f[2]*f[3]) = 1440 and 1440 %114 is 72

http://www.codechef.com/problems/FOMBRO

分奇偶两种情况考虑。

奇数(9):

19 28 37 46 55 64 73 82 91

19 21 31 41 51 61 71 81 91

19 21 32 42 52 62 72 82 91

19 21 32 43 53 63 73 82 91

19 21 32 43 54 64 73 82 91

偶数(8):

18 27 36 45 54 63 72 81

18 21 31 41 51 61 71 81

18 21 32 42 52 62 72 81

18 21 32 43 53 63 72 81

18 21 32 43 54 63 72 81

由此,规律应该很好看懂了吧~

#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<map>
#include<cmath>
#include<vector>
#include<stdlib.h>
#include<cstdio>
#define ll long long
using namespace std;
ll add[1000001];
ll x[1000001];
int main(){
	int t;
	cin>>t;
	while(t--){
		ll n,m,q,a;
		scanf("%lld %lld %lld",&n,&m,&q);
		ll p=n/2+1,l,r;
		if(n%2==0){
			l=p;r=p;
			add[0]=p%m;
		}
		else{
			l=p;r=p+1;
			add[0]=((p%m)*((p+1)%m))%m;
		}
		int k=0;
		for(int i=l-1,j=r+1;j<=n;--i,++j){
			add[++k]=(((add[k-1]%m)*(i%m))%m*(j%m))%m; //这里取模WA了好多下。。。以后注意
		}
		x[0]=1%m;
		for(int i=1;i<=n/2;++i){
			x[i]=((x[i-1]%m)*(add[k]%m))%m;
			k--;
		}
		while(q--){
			scanf("%lld",&a);
			if(a>n/2)
				a=n-a;
			printf("%lld\n",x[a]);
		}
	}
	return 0;
}


你可能感兴趣的:(【codechef】Zombinatorial(找规律))