列表

详情


NC50601. 有趣的数列

描述

我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件:
  1. 它是从1到2n共2n个整数的一个排列
  2. 所有的奇数项满足,所有的偶数项满足
  3. 任意相邻的两项满足奇数项小于偶数项,
即:。任务是:对于给定的n,请求出有多少个不同的长度为2n的有趣的数列。因为最后的答案可能很大,所以只要求输出答案的值。

输入描述

只包含用空格隔开的两个整数n和P。

输出描述

仅含一个整数,表示不同的长度为2n的有趣的数列个数的值。

示例1

输入:

3 10

输出:

5

说明:

对应的5个有趣的数列分别为{1,2,3,4,5,6 }, {1,2,3,5,4,6 }, {1,3,2,4,5,6 }, {1,3,2,5,4,6 }, {1,4,2,5,3,6 }。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 28ms, 内存消耗: 2896K, 提交时间: 2022-08-10 16:14:15

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int N = 2000010;
int primes[N], cnt;
bool st[N];

int n, mod;

void init(int n) {
    for (int i = 2; i <= n; i++) {
        if(!st[i]) primes[cnt++] = i;
        for (int j = 0; primes[j] * i <= n; j++) {
            st[primes[j] * i] = true;
            if(i % primes[j] == 0) break;
        }
    }
}

int qmi(int a, int b) {
    int res = 1;
    for (; b; b >>= 1, a = 1ll * a * a % mod) {
        if(b & 1) res = 1ll * res * a % mod;
    }
    return res;
}

int get(int n, int p) {
    int s = 0;
    for (; n; n /= p) s += n / p;
    return s;
}

int C(int a, int b) {
    int res = 1;
    for (int i = 0; i < cnt; i++) {
        int p = primes[i];
        int s = get(a, p) - get(b, p) - get(a - b, p);
        res = 1ll * res * qmi(p, s) % mod;
    }
    return res;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> mod;
    init(2 * n);

    cout << (C(2 * n, n) - C(2 * n, n - 1) + mod) % mod;

    return 0;
}

C++ 解法, 执行用时: 65ms, 内存消耗: 32752K, 提交时间: 2022-04-06 11:00:50

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll prime[2000005],a[2000005],come[2000005];
ll ans=1,n,p,cnt,mod;
ll fpow(ll a,ll b)
{
	ll ans;
	for(ans=1;b;b=b/2,a=a*a%mod)
	if(b&1)
	ans=ans*a%mod;
	return ans;
}
int main()
{
	cin>>n>>mod;
	for(ll i=2;i<=n*2;i++) {
		if(!come[i])
		prime[++cnt]=i;
		for(ll j=1;j<=cnt&&prime[j]*i<=n*2;j++)
		come[prime[j]*i]=i;
	}
	for(ll i=2;i<=n;i++)a[i]=-1;
	for(ll i=n+2;i<=2*n;i++)a[i]=1;
	for(ll i=n*2;i>1;i--)
	if(come[i]) {
		a[come[i]]+=a[i];
		a[i/come[i]]+=a[i];
	}
	else ans=ans*fpow(i,a[i])%mod;
	cout<<ans;
	return  0;
}

上一题