UPC6575: 11(组合数)

益,莫过一日曝十日寒。

6575: 11

时间限制: 1 Sec  内存限制: 128 MB
提交: 135  解决: 44
[提交] [状态] [讨论版] [命题人:admin]

题目描述

You are given an integer sequence of length n+1, a1,a2,…,an+1, which consists of the n integers 1,…,n. It is known that each of the n integers 1,…,n appears at least once in this sequence.
For each integer k=1,…,n+1, find the number of the different subsequences (not necessarily contiguous) of the given sequence with length k, modulo 109+7.
Notes
If the contents of two subsequences are the same, they are not separately counted even if they originate from different positions in the original sequence.
A subsequence of a sequence a with length k is a sequence obtained by selecting k of the elements of a and arranging them without changing their relative order. For example, the sequences 1,3,5 and 1,2,3 are subsequences of 1,2,3,4,5, while 3,1,2 and 1,10,100 are not.

Constraints
1≤n≤105
1≤ai≤n
Each of the integers 1,…,n appears in the sequence.
n and ai are integers.

输入

Input is given from Standard Input in the following format:
n
a1 a2 ... an+1

输出

Print n+1 lines. The k-th line should contain the number of the different subsequences of the given sequence with length k, modulo 109+7.

样例输入

3
1 2 1 3

样例输出

3
5
4
1

提示

There are three subsequences with length 1: 1 and 2 and 3.
There are five subsequences with length 2: 1,1 and 1,2 and 1,3 and 2,1 and 2,3.
There are four subsequences with length 3: 1,1,3 and 1,2,1 and 1,2,3 and 2,1,3.
There is one subsequence with length 4: 1,2,1,3.

来源/分类

ABC066&ARC077 

小结:粗心使人进步,最后答案ans1-ans2+mod,忘记加mod导致特么一直服的不行。。。

题意:输入n有个n+1的序列,其中1到n至少出现一次,然后有个数会出现两次,问你长度为K的序列1\leq K\leq n+1,会出现多少个不同的子序列。

思路:组合数问题啦,如果不考虑重复的数字的话那么总共有C(n+1,k)中情况,但是有重复的,重复的就是比如1 2 1 3,第一个1和第二1能都跟3组成1,3,但这是一种情况,所以减去重复的,那么重复的怎么求呢,其实就是从第一个重复数字出现位置之前所有数和第二个重复数字出现的位置之后的所有数的和中选出i-1 跟重复数字就是我们要减去的答案。

最近写代码越来越浓缩了,嘤嘤嘤

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define FIN freopen("D://code//in.txt", "r", stdin)
#define ppr(i,x,n) for(int i = x;i <= n;i++)
#define rpp(i,n,x) for(int i = n;i >= x;i--)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
inline ll qow(ll a,ll b){ll r=1,t=a; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;}
inline int read() {//读入挂
    int ret = 0, c, f = 1;
    for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
    if(c == '-') f = -1, c = getchar();
    for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
    if(f < 0) ret = -ret;
    return ret;
}
int n;
ll fac[maxn],inv[maxn];
int vis[maxn],a[maxn];
int main()
{
    IO;cin>>n;
    int first,second;fac[0] = 1;
    memset(vis,0,sizeof(vis));
    ppr(i,1,n+1){fac[i]=fac[i-1]*i%mod;}
    inv[n+1]= qow(fac[n+1],mod-2);
    rpp(i,n+1,1){inv[i-1]=inv[i]*i%mod;}
    ppr(i,1,n+1){cin>>a[i];if(vis[a[i]]){second=i;first=vis[a[i]];break;}vis[a[i]]=i;}
    ppr(i,1,n+1)
    {
        ll ans,ans1,ans2;
        ll num = n+first-second;
        ans1 = fac[n+1]*inv[i]%mod*inv[n+1-i]%mod;
        ans2 = fac[num]*inv[i-1]%mod*inv[num-i+1]%mod;
        ans = (ans1-ans2+mod)%mod;
        printf("%lld\n",ans);
         
    }
}

猜你喜欢

转载自blog.csdn.net/Pandapan1997/article/details/81428411
今日推荐