bzoj1485: [HNOI2009]有趣的数列

卡特兰数

http://www.cnblogs.com/zhber/p/4181190.html

 

2016.3.4 updated:

无意中翻出来了,发现之前的写的跑的很慢,就去看了下

发现分解质因数可以是logn的而我写的n0.5的。

 

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>

using namespace std;

void setIO(const string& s) {
	freopen((s + ".in").c_str(), "r", stdin);
	freopen((s + ".out").c_str(), "w", stdout);
}
template<typename Q> Q read(Q& x) {
	static char c, f;
	for(f = 0; c = getchar(), !isdigit(c); ) if(c == '-') f = 1;
	for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	if(f) x = -x;
	return x;
}
template<typename Q> Q read() {
	static Q x; read(x); return x;
}

typedef long long LL;
const int LIM = 2000000, N = 1000000;

int primes[N], tot, mn[LIM+1];
bool flag[LIM+1];

void get_prime(int n) {
	for(int i = 2; i <= n; i++) {
		if(!flag[i]) primes[tot] = i, mn[i] = tot++;
		for(int j = 0; j < tot; j++) {
			int k = primes[j];
			if((LL) i * k > n) break;
			flag[i * k] = 1;
			mn[i * k] = j;
			if(i % k == 0) break;
		}
	}
}

int num[N];

void add(int x, int sign) {
	while(x != 1) {
		num[mn[x]] += sign;
		x /= primes[mn[x]];
	}
}

LL qpow(LL a, int b, int p) {
	a %= p;
	for(LL c = 1; ; (a *= a) %= p) {
		if(b & 1) (c *= a) %= p;
		if(!(b >>= 1)) return c;
	}
}

int main() {
#ifdef DEBUG
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	
	int n, p;
	scanf("%d%d", &n, &p);
	get_prime(n * 2);
	for(int i = n * 2; i > n; i--) add(i, 1);
	for(int i = n; i > 1; i--) add(i, -1);
	add(n + 1, -1);
	
	int res = 1;
	for(int i = 0; i < tot; i++) if(num[i]) {
		res = (LL) res * qpow(primes[i], num[i], p) % p;
	}
	printf("%d\n", res);
	
	return 0;
}

 

posted @ 2016-01-05 20:20  Showson  阅读(227)  评论(0编辑  收藏  举报