CodeForces - 660E Different Subsets For All Tuples (组合数学&DP)好题

CodeForces - 660E
Different Subsets For All Tuples
Time Limit: 2000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u

Submit Status

Description

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 modulo109 + 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.

Sample Input

Input
1 3
Output
6
Input
2 2
Output
14
Input
3 3
Output
174

Source

Educational Codeforces Round 11
//题意:输入n,m,
表示从1--m这m个数字中选出n个数(相同的数字可重复取),问所有情况的所有子集的个数。
//思路:
可以说规律只找到n等于2就找不下去了(智商太低了。。。),看了大神的还是不怎么懂。。
大神的思路和代码:

考虑dp

dp[i][j]表示长度为i,以字符j结尾的答案是多少

dp[i][j]=sigma(dp[i-1][k]*2-dp[pre[j]-1][k])

然后这个玩意儿显然对于任意的j的都是一样的,而且pre[j]前面的每个位置都是可能的,这里的dp是个前缀和,所以直接扣除就可以了

那么直接化简为:dp[i]=dp[i-1]*(2m-1)

但是这个dp是没有考虑空串的

那么在加上空串就好了,所以答案就是

dp[i] = dp[i-1]*(2m-1)+m^(i-1)

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
#include<iostream>
#define INF 0x3f3f3f3f
#define ull unsigned long long
#define ll long long
#define IN __int64
#define N 2010
#define M 1000000007
using namespace std;
int main()
{
	int n,m;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		ll ans=2*m;
		ll tmp=1;
		for(int i=2;i<=n;i++)
		{
			tmp=tmp*m%M;
			ans=(ans*(2*m-1)%M+tmp+M)%M;
		}
		printf("%lld\n",ans);
	}
	return 0;
} 

你可能感兴趣的:(CodeForces - 660E Different Subsets For All Tuples (组合数学&DP)好题)