zoukankan      html  css  js  c++  java
  • bzoj1485 [HNOI2009]有趣的数列

    Description

     我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件:

        (1)它是从1到2n共2n个整数的一个排列{ai};

        (2)所有的奇数项满足a1<a3<…<a2n-1,所有的偶数项满足a2<a4<…<a2n

        (3)任意相邻的两项a2i-1与a2i(1≤i≤n)满足奇数项小于偶数项,即:a2i-1<a2i

        现在的任务是:对于给定的n,请求出有多少个不同的长度为2n的有趣的数列。因为最后的答案可能很大,所以只要求输出答案 mod P的值。

    Input

    输入文件只包含用空格隔开的两个整数n和P。输入数据保证,50%的数据满足n≤1000,100%的数据满足n≤1000000且P≤1000000000。

    Output

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

    Sample Input

    3 10

    Sample Output

    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)。

    正解:卡特兰数。

    打表以后发现是卡特兰数,然后直接分解质因数求组合数就行了。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define N (1000010)
     6 
     7 using namespace std;
     8 
     9 int prime[N],num[N],n,p,cnt,phi,inv,ans;
    10 
    11 il int qpow(RG int a,RG int b){
    12   RG int ans=1;
    13   while (b){
    14     if (b&1) ans=1LL*ans*a%p;
    15     a=1LL*a*a%p,b>>=1;
    16   }
    17   return ans;
    18 }
    19 
    20 il void divide(RG int n){
    21   phi=n;
    22   for (RG int i=2;i*i<=n;++i){
    23     if (n%i) continue;
    24     while (n%i==0) n/=i;
    25     prime[++cnt]=i,phi=phi/i*(i-1);
    26   }
    27   if (n!=1) prime[++cnt]=n,phi=phi/n*(n-1); return;
    28 }
    29 
    30 il void get(RG int n,RG int v){
    31   for (RG int i=1;i<=n;++i){
    32     RG int x=i;
    33     for (RG int j=1;j<=cnt;++j){
    34       if (x%prime[j]) continue;
    35       while (x%prime[j]==0) num[j]+=v,x/=prime[j];
    36     }
    37     if (v==1) ans=1LL*ans*x%p;
    38     else inv=1LL*inv*x%p;
    39   }
    40 }
    41 
    42 int main(){
    43 #ifndef ONLINE_JUDGE
    44   freopen("sequence.in","r",stdin);
    45   freopen("sequence.out","w",stdout);
    46 #endif
    47   cin>>n>>p; divide(p),ans=inv=1;
    48   get(2*n,1),get(n,-1),get(n+1,-1);
    49   for (RG int i=1;i<=cnt;++i)
    50     ans=1LL*ans*qpow(prime[i],num[i])%p;
    51   ans=1LL*ans*qpow(inv,phi-1)%p;
    52   cout<<ans; return 0;
    53 }
  • 相关阅读:
    C++ Primer Chap13
    Visual Studio 2005调试ASP脚本程序的方法
    我所关注的Tech•Ed 2010(一)云计算
    解决VS2008中日文代码注释乱码的问题
    [翻译]为EXPRESSION WEB 4添翼—如何支持HTML5设计开发!
    文件数量较多的情况下如何提高刻录速度(调用IMAPI2实现DVD刻录功能)
    如何用C++实现安全Remove USB Device
    Microsoft Press ebookProgramming Windows Phone 7
    我所关注的Tech•Ed 2010(二)—Windows Phone
    我所关注的Tech•Ed 2010(三)移动云计算应用开发
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7526781.html
Copyright © 2011-2022 走看看