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

      一眼卡特兰数...写完才发现不对劲,样例怎么输出$0$...原来模数不一定是质数= =...

      第一次见到模数不是质数的求组合数方法$(n,mleq 10^7)$,记录一下...

      先对于$1$~$n$的每个数筛出最小的质因子(我肯定是写埃式筛啦),那么乘上一个数$x$相当于乘上$x$的所有质因子,所以从大到小扫一遍每一个数,若$x$被乘了$1$次且$x$不是质数,那么就给$x$的最小质因子$mn_x$和$frac{x}{mn_x}$的次数+$1$,显然这样最后只会剩下质因子有记录次数,那么这个次数就是质因子的指数了。

      如果求$C(n,m)$,不妨设$n-mleq m$,那么$m+1$~$n$被乘了$1$次,$1$~$n-m$被除了$1$次,也就是被乘了$-1$次,那么这些数的质因子都应该被减去相应次数。会不会有质因子被减到负数了?我们知道组合数一定是正整数,所以肯定不会出负数啦~

      最后扫一遍所有质数,快速幂一下就可以求得组合数了,$n$以内的质数个数是$O(frac{n}{logn})$级别的,快速幂是$O(logn)$的,所以复杂度是$O(n)$的。

      对于这题使用卡特兰数的$C(2n,n)/(n+1)$的公式会比较好一些,不算$n+1$的贡献就好了

    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int maxn=2000010, inf=1e9;
    int n, mod, ans;
    int p[maxn], mn[maxn], cnt[maxn];
    bool v[maxn];
    inline void read(int &k)
    {
        int f=1; k=0; char c=getchar();
        while(c<'0' || c>'9') c=='-'&&(f=-1), c=getchar();
        while(c<='9' && c>='0') k=k*10+c-'0', c=getchar();
        k*=f;    
    } 
    inline void getp()
    {
        for(int i=2;i<=n<<1;i++)
        if(!v[i])
        {
            p[++p[0]]=i;
            for(int j=i<<1;j<=n<<1;j+=i) v[j]=1, !mn[j] && (mn[j]=i);
        }
    }
    inline int power(int a, int b)
    {
        int ans=1;
        for(;b;b>>=1, a=1ll*a*a%mod)
        if(b&1) ans=1ll*ans*a%mod;
        return ans;
    }
    inline void add(int x, int delta)
    {
        cnt[x]+=delta;
        if(v[x])
        {
            cnt[mn[x]]+=cnt[x];
            cnt[x/mn[x]]+=cnt[x];
            cnt[x]=0;
        }
    }
    int main()
    {
        read(n); read(mod); getp(); ans=1;
        for(int i=n<<1;i>n+1;i--) add(i, 1);
        for(int i=n;i>1;i--) add(i, -1);
        for(int i=1;i<=p[0];i++)
        ans=1ll*ans*power(p[i], cnt[p[i]])%mod;
        printf("%d
    ", ans);
    }
    View Code
  • 相关阅读:
    Linux安全应用之防垃圾邮件服务器的构建
    Postfix邮件系统安装配置视频
    Linux常用的安全工具
    Linux系统安全加固(一)
    全球开源软件发展趋势分析
    安装配置FreeBSD9全过程体验
    P1441-砝码称重
    POJ-2376 Cleaning Shifts
    P1514-引水入城
    P1378-油滴扩展
  • 原文地址:https://www.cnblogs.com/Sakits/p/8437150.html
Copyright © 2011-2022 走看看