• 【组合数学】cf660E. Different Subsets For All Tuples


    比较套路的组合数学题

    For a sequence a of n integers between 1 and m, inclusive, denote f(a) as the number of distinct subsequences of a (including the empty subsequence).

    You are given two positive integers n and m. Let S be the set of all sequences of length n consisting of numbers from 1 to m. Compute the sum f(a) over all a in S modulo 109 + 7.

    Input

    The only line contains two integers n and m (1 ≤ n, m ≤ 106) — the number of elements in arrays and the upper bound for elements.

    Output

    Print the only integer c — the desired sum modulo 109 + 7.


    题目大意

    一个长度为 $N$ 的数列,每个位置上的数字可以是$[1,M]$,这样的数列一共有$M^N$个。对于$M^N$这个数列,求其本质不同的子序列个数之和。答案对 $P$ 取模。

    $1≤N,M≤10^6,2≤P≤10^9+7$,保证 $P$ 是质数。

    题目分析

    正经推式子

    首先注意到对于长度相同的子序列,它们在答案中的贡献是相同的。那么问题变为了计算$f_i$:长度为$i$的子序列对答案的贡献。

    为了保证不算重贡献,我们所求的子序列必须是在全数列中唯一出现一次的方案。也就是说,设长为$i$的子序列是${a_1,a_2cdots a_i}$,那么$a_1$之前不能出现$a_1$;$a_1cdots a_2$之间不能出现$a_2$;$cdots$以此类推。从最基础的式子考虑起:枚举一个数$j$为长度为$i$的子序列在序列中的结束位置。则有:

    $sum f_i=sumlimits_{i=1}^{n}sumlimits_{j=i}^{n}m^i{j-1choose i-1}m^{n-j}(m-1)^{j-i}$

    其中,$m^i​$表示这个长度为$i​$的序列有几种本质不同的方案数;${j-1choose i-1}​$表示除了强制固定在$j​$位的最后一个数字,剩下的可在前$j-1​$中任意选取;$m^{n-j}​$表示$j+1cdots n​$的位置可以任意排列数字;$(m-1)^{j-i}​$表示前$j-i​$位置由于有且仅有一次我们所强制的子序列,那么每个位置只能安排$m-1​$个数。

    按照常规套路,把$i,j​$的两重循环互换位置:

    $sum f_i=sumlimits_{j=1}^{n}sumlimits_{i=1}^{j}{j-1choose i-1}m^{n-j+i}(m-1)^{j-i}$

    注意到后一部分是一个类似二项式展开的形式,因此把$i$改为$0cdots j-1$的循环。

    $sum f_i=sumlimits_{j=1}^{n}m^{n-j+1}sumlimits_{i=0}^{j-1}{j-1choose i}m^i(m-1)^{j-i-1}$

    $sum f_i=sumlimits_{j=1}^{n}m^{n-j+1}(2m-1)^{j-1}$

    那么所求答案就是$ans=sum f_i+M^N$.因此可以使用$O(nlog n)$或$O(n)$的复杂度通过此题。

     1 #include<bits/stdc++.h>
     2 #define MO 1000000007
     3 
     4 int n,m;
     5 long long ans;
     6 
     7 int qmi(int a, int b)
     8 {
     9     int ret = 1;
    10     for (; b; b>>=1, a=1ll*a*a%MO)
    11         if (b&1) ret = 1ll*ret*a%MO;
    12     return ret;
    13 }
    14 int main()
    15 {
    16     scanf("%d%d",&n,&m);
    17     for (int i=1; i<=n; i++)
    18         ans = (ans+1ll*qmi(m, n-i+1)*qmi(2*m-1, i-1)%MO)%MO;
    19     printf("%lld
    ",(ans+1ll*qmi(m, n))%MO);
    20     return 0;
    21 }

    关于找规律的技巧

    考虑答案大概是一个$ans=sumlimits_{i=1}^n k_1(m+a)k_2(2m+b)k_3(m^2+c)cdots$的形式。

    那么就依据暴力来观察答案。

    当然前提条件是暴力写得又快又准……

    END

  • 相关阅读:
    RfcDestinationManager.UnregisterDestinationConfiguration时报错cannot unregister the given destination configuration
    SVN文件自动加锁-Win7
    linux 命令详解 sort
    Tensorflow的采样方法:candidate sampling(zhuan)
    (转载)机器学习中的目标函数、损失函数、代价函数有什么区别
    tensorflow dropout
    textcnn
    tensorflow学习笔记(三十九):双向rnn
    sklearn one_hot 操作
    sklearn 划分数据集。
  • 原文地址:https://www.cnblogs.com/antiquality/p/10533537.html
Copyright © 2020-2023  润新知