题目大意
求长度为n的每项为[1,m]的所有数列的本质不同子序列个数和
n,m<=10^6
题解
洛谷黑题感觉过了,想想还是能想出来的
容斥很难搞所以直接算
对于每种子序列计算,只算在序列中第一次出现时算
“第一次”的定义:在序列上把查找的子序列一位位跳,每次跳最近的那个所得到的位置集合就是第一次出现的
设序列为a出现位置为b,则在b[i-1]+1~b[i]-1区间内都不能有a[i],只有m-1种方案,在b[i]以及>b[k]位置有m种方案
枚举b[k]和k可得
(ans=m^n+sum_{i=1}^{n}{sum_{j=1}^{i}{(m-1)^{i-j}C_{i-1}^{j-1}m^jm^{n-i}}})
考虑式子意义,就是[1,i-1]可以乘m或m-1,[i,n]乘n
合并一下就是
(ans=m^n+sum_{i=1}^{n}{(2m-1)^{i-1}m^{n-i+1}})
code
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define C(n,m) (jc[n]*Jc[m]%1000000007*Jc[(n)-(m)]%1000000007)
#define mod 1000000007
#define Mod 1000000005
#define ll long long
//#define file
using namespace std;
ll jc[1000001],Jc[1000001],w[1000001],p[1000001],P[1000001],ans;
int n,m,i,j,k,l;
int main()
{
#ifdef file
freopen("CF660E.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
if (m==1) {printf("%d
",n+1);return 0;}
jc[0]=jc[1]=Jc[0]=Jc[1]=w[1]=p[0]=P[0]=1;p[1]=m+m-1;P[1]=m;
fo(i,2,n)
w[i]=mod-w[mod%i]*(mod/i)%mod,jc[i]=jc[i-1]*i%mod,Jc[i]=Jc[i-1]*w[i]%mod,p[i]=p[i-1]*(m+m-1)%mod,P[i]=P[i-1]*m%mod;
fo(i,1,n)
ans=(ans+p[i-1]*P[n-i+1])%mod;
printf("%lld
",(ans+P[n])%mod);
}