Ejemplo n.º 1
0
    public long count(int N, int M, int K)
    {
        int  i, j, k;
        int  len = N - M + 1;
        long res = 0;

        if (K == 0)
        {
            return((long)(Math.Pow(26, N) + 1e-9));
        }

        long[] mul = new long[len + 1];
        if (len >= K)
        {
            mul[K] = 1;
        }
        for (i = K + 1; i <= len; i++)
        {
            long now = 0;
            for (j = 0; j < i; j++)
            {
                now -= c(i, j) * mul[j];
            }
            mul[i] = now + 1;
        }

        for (i = 0; i < (1 << len); i++)
        {
            int       count = 0;
            Unionfind uni   = new Unionfind(N);
            for (j = 0; j < len; j++)
            {
                if ((i >> j) % 2 == 1)
                {
                    count++;
                    for (k = 0; k <= (M - 1) / 2; k++)
                    {
                        uni.connect(j + k, j + M - k - 1);
                    }
                }
            }
            if (K > count)
            {
                continue;
            }
            long now = 1;
            for (j = 0; j < N; j++)
            {
                if (uni.root(j) == j)
                {
                    now *= 26;
                }
            }
            res += now * mul[count];
        }
        return(res);
    }
Ejemplo n.º 2
0
    public long count(int N, int M, int K)
    {
        int i, j, k;
        int len = N - M + 1;
        long res = 0;
        if (K == 0) return (long)(Math.Pow(26, N) + 1e-9);

        long[] mul = new long[len + 1];
        if (len >= K) mul[K] = 1;
        for (i = K + 1; i <= len; i++)
        {
            long now = 0;
            for (j = 0; j < i; j++)
            {
                now -= c(i, j) * mul[j];
            }
            mul[i] = now + 1;
        }

        for (i = 0; i < (1 << len); i++)
        {
            int count = 0;
            Unionfind uni = new Unionfind(N);
            for (j = 0; j < len; j++)
            {
                if ((i >> j) % 2 == 1)
                {
                    count++;
                    for (k = 0; k <= (M - 1) / 2; k++)
                    {
                        uni.connect(j + k, j + M - k - 1);
                    }
                }
            }
            if (K > count) continue;
            long now = 1;
            for (j = 0; j < N; j++)
            {
                if (uni.root(j) == j)
                {
                    now *= 26;
                }
            }
            res += now * mul[count];
        }
        return res;
    }