Atcoder arc077 D - 11 组合

Link

题意:给出n个数,其中有一个数会出现两次,其余数只出现一次,问不同长度且不同的子串的数量。取模1e9+7

思路:组合求出所有情况,减去重复情况,注意用逆元即可

 

/** @Date    : 2017-07-06 09:56:44
  * @FileName: atcoder077 D 组合.cpp
  * @Platform: Windows
  * @Author  : Lweleth (SoungEarlf@gmail.com)
  * @Link    : https://github.com/
  * @Version : $Id$
  */
#include <bits/stdc++.h>
#define LL long long
#define PII pair
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 1e5+20;
const double eps = 1e-8;
const LL mod = 1e9 + 7;

LL a[N];
LL inv[N];
LL fa[N];
LL n;

void init()
{
	fa[0] = fa[1] = 1;
    inv[1] = 1;
    for(LL i = 2; i < N; i++)
    {
        fa[i] = fa[i-1] * i % mod;
        inv[i] = (mod - mod / i) * inv[mod % i] % mod;
    }
    inv[0] = 1;
    for(int i = 1; i < N; i++)
    	(inv[i] *= inv[i - 1]) %= mod;
}

LL C(LL n, LL k)
{
	LL ans = 0;
	if(k > n)
		return ans;
	ans = ((fa[n] * inv[k] % mod) * inv[n - k]) % mod;
	return ans;
}
int main()
{
	init();
	while(cin >> n)
	{
		map<LL, int>q;
		LL p = 0;
		for(int i = 1; i <= n + 1; i++)
		{
			scanf("%lld", a + i);
			if(!q[a[i]])
				q[a[i]] = i;
			else 
				p = i;
		}
		for(int i = 0; i <= n; i++)
		{
			LL ans = 0;
			ans = (ans + C(n + 1, i + 1)) % mod;
			ans = (ans - C(n - p + q[a[p]], i)) % mod;
			while(ans < 0)
				ans += mod;
			printf("%lld\n", ans);
		}
	}
    return 0;
}
posted @ 2017-07-16 09:17  Lweleth  阅读(237)  评论(0编辑  收藏  举报