• bzoj 1485 : [HNOI2009]有趣的数列


      

    1485: [HNOI2009]有趣的数列

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 1284  Solved: 688
    [Submit][Status][Discuss]

    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

     
    这道题正着想很不好想,所以我们可以倒过来想。
    把[1,2n]的排列当成2n个位置,原数列中每个位置当成一个数x,那么考虑从1到2n依次填现在的每个位置。

    然后就很好做了,对于每个奇数的x,填完后一定是有序的,偶数同理,所以可以把奇数视为0,偶数视为1,得到一个合法的01序列后一定可以按顺序还原出数列。

    那么当前填了a个0,a+1个1,那么说明原数列中有个位置2i选了,而2i-1还没选,则a[2i-1]>a[2i],显然是违法的。

    因为每个时刻0>1,通项为卡特兰数列。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define ll long long
     6 #define N 2000005
     7 using namespace std;
     8 int n,p;
     9 int su[N],tot,pr[N],fan[N];
    10 const int inf = 2000000;
    11 void shai()
    12 {
    13     for(int i=2;i<=inf;i++)
    14     {
    15         if(!pr[i])
    16         {
    17             su[++tot]=i;
    18             fan[i]=tot;
    19             pr[i]=i;
    20         }
    21         for(int j=1;j<=tot&&su[j]<=pr[i]&&su[j]*i<=inf;j++)
    22         {
    23             pr[su[j]*i]=su[j];
    24         }
    25     }
    26     return ;
    27 }
    28 int num[N];
    29 inline void fft(int x,int z)
    30 {
    31     while(x!=1)
    32     {
    33         num[fan[pr[x]]]+=z;
    34         x/=pr[x];
    35     }
    36     return ;
    37 }
    38 int main()
    39 {
    40     scanf("%d%d",&n,&p);
    41     shai();
    42     for(int i=2;i<=n*2;i++)fft(i,1);
    43     for(int i=2;i<=n;i++)fft(i,-2);
    44     fft(n+1,-1);
    45     ll ans=1;
    46     for(int i=1;i<=tot;i++)
    47     {
    48         for(int j=1;j<=num[i];j++)
    49         {
    50             ans=ans*su[i]%p;
    51         }
    52     }
    53     printf("%lld
    ",ans);
    54     return 0;
    55 }

      

      

  • 相关阅读:
    JQuery easyui (4)Tooltip (提示组件) 组件
    JQuery easyui (3) Resizable(调整大小)组件
    洛谷 P1919 【模板】A*B Problem升级版(FFT快速傅里叶)
    2019 ACM-ICPC 上海网络赛 B. Light bulbs (差分)
    POJ 1474 Video Surveillance (半平面交)
    HDU 5119 Happy Matt Friends (背包DP + 滚动数组)
    洛谷 P1613 跑路 (倍增 + DP + 最短路)
    POJ 1279 Art Gallery (半平面交)
    POJ 3130 How I Mathematician Wonder What You Are! (半平面交)
    POJ 2451 Uyuw's Concert (半平面交)
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6586130.html
Copyright © 2020-2023  润新知