zoukankan      html  css  js  c++  java
  • CodeForces

    As Gerald, Alexander, Sergey and Gennady are already busy with the usual New Year chores, Edward hastily decorates the New Year Tree. And any decent New Year Tree must be decorated with a good garland. Edward has lamps of m colors and he wants to make a garland from them. That garland should represent a sequence whose length equals L. Edward's tree is n layers high and Edward plans to hang the garland so as to decorate the first layer with the first l1 lamps, the second layer — with the next l2 lamps and so on. The last n-th layer should be decorated with the last ln lamps,

    Edward adores all sorts of math puzzles, so he suddenly wondered: how many different ways to assemble the garland are there given that the both following two conditions are met:

    1. Any two lamps that follow consecutively in the same layer should have different colors.
    2. The sets of used colors in every two neighbouring layers must be different. We consider unordered sets (not multisets), where every color occurs no more than once. So the number of lamps of particular color does not matter.

    Help Edward find the answer to this nagging problem or else he won't manage to decorate the Tree by New Year. You may consider that Edward has an unlimited number of lamps of each of m colors and it is not obligatory to use all m colors. The garlands are considered different if they differ in at least one position when represented as sequences. Calculate the answer modulo p.


    Input

    The first line contains three integers n, m and p (1 ≤ n, m ≤ 106, 2 ≤ p ≤ 109) which are the number of the tree's layers, the number of the lamps' colors and module correspondingly. The next line contains n integers li (1 ≤ li ≤ 5000, ).

    Output

    Print the only integer — the number of garlands modulo p.

    Examples
    Input
    3 2 1000
    3 1 2
    Output
    8
    Input
    2 3 1000
    2 2
    Output
    24
    Input
    1 1 1000
    5
    Output
    0
    Note

    In the first sample the following variants are possible: 121|1|12, 121|1|21, 121|2|12, 121|2|21, 212|1|12, 212|1|21, 212|2|12, 212|2|21. In the second sample the following variants are possible: 12|13, 12|23, 12|31, 12|32 and so on.

    Figure for the first sample:

    题意:给定一棵树,数有N层,你有M种颜色,让你求染色方案数,结果模P;需要满足同一层的相邻颜色不同,而且相邻层的颜色集合不能相同。

    思路:由于P不一定是素数,我们不能出现除法。 所以需要加减法。

    我们用f[i][j]表示只考虑一层,前面i个不同的点染j种相同的颜色的方案数。

        联系第二类斯特林数f[i][j]=f[i-1][j-1]+f[i-1][j]*(j-1);注意到这里的颜色是没有标号的,而且没有排序。

    dp[i][j]表示第i层用j种颜色发方案数。那么dp[i][j]=Σdp[i-1][k]*A(M,k)-dp[i-1][j]*FAC(j);

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=5010;
    const int maxm=1000010;
    int f[maxn][maxn],sum[maxm],A[maxn],F[maxn];
    int dp[2][maxn],a[maxm];
    int main()
    {
        int N,M,P,x;
        scanf("%d%d%d",&N,&M,&P);
        f[0][0]=1;
        rep(i,1,5000) rep(j,1,i)
           f[i][j]=(1LL*f[i-1][j]*(j-1)%P+f[i-1][j-1])%P;
        //按照第二类斯特林数的理解,f[i][j]表示i个不同的下标,用j种相同的颜色染色。是没有标号的,所以最后要乘A。
        sum[0]=1; A[0]=1; F[0]=1;
        rep(i,1,min(M,5000)) A[i]=1LL*A[i-1]*(M+1-i)%P;
        rep(i,1,min(M,5000)) F[i]=1LL*F[i-1]*i%P;
        rep(i,1,N) {
            scanf("%d",&a[i]);
            rep(j,1,min(a[i],M)){
                dp[i&1][j]=1LL*f[a[i]][j]*A[j]%P*sum[i-1]%P; //由于f是未标号的,A
                if(a[i-1]>=j) (((dp[i&1][j]-=1LL*F[j]*f[a[i]][j]%P*dp[(i&1)^1][j]%P)%=P)+=P)%=P; //dp的已经标号了的,所以颜色是固定了的
    //只需要排列第i行的j种颜色
    (sum[i]+=dp[i&1][j])%=P; } } printf("%d ",sum[N]); return 0; }
  • 相关阅读:
    以下哪个Hibernate主键生成策略是实现主键按数值顺序递增的?
    编写一个Filter,除继承HttpServlet类外还需要( )。
    有关JSP隐式对象,以下( )描述正确。
    JAVA通信系列三:Netty入门总结
    JAVA通信系列二:mina入门总结
    JAVA通信系列一:Java Socket技术总结
    大型网站架构系列:缓存在分布式系统中的应用(三)
    大型网站架构系列:缓存在分布式系统中的应用(二)
    大型网站架构系列:缓存在分布式系统中的应用(一)
    大型网站架构系列:负载均衡详解(4)
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10149613.html
Copyright © 2011-2022 走看看