AtCoder Beginner Contest 066(CD)

tech2025-06-22  1

AtCoder Beginner Contest 066 (CD)

C - pushpush

思路:双端队列+指针指向即可。

D - 11

思路:组合数学。

考虑对于 k k k用所有方案数 − - 重复的方案数。

总方案数为: C ( n + 1 , k ) C(n+1,k) C(n+1,k)

假设重复的那个数为 x x x,两个数的位置分别为: p 1 < p 2 p_1<p_2 p1<p2

当且仅当所选择的 k k k个数只包含一个 x x x,且不含 ( p 1 , p 2 ) (p_1,p_2) (p1,p2)之间的数则方案会重复。

所以重复的方案数等价为:从 n + 1 − ( p 2 − p 1 + 1 ) n+1-(p_2-p_1+1) n+1(p2p1+1)个数中选择 k − 1 k-1 k1个数 (因为 x x x必须选)

即: C ( n − ( p 2 − p 1 ) , k − 1 ) C(n-(p_2-p_1),k-1) C(n(p2p1),k1)

所以对于 k k k,答案为: C ( n + 1 , k ) − C ( n − ( p 2 − p 1 ) , k − 1 ) C(n+1,k)-C(n-(p_2-p_1),k-1) C(n+1,k)C(n(p2p1),k1)

可用费马小定理或者阶乘逆元递推即可。

fac[0]=1; for(int i=1;i<=n+1;i++){ scanf("%d",&a[i]); if(vis[a[i]]) d=(i-vis[a[i]]); vis[a[i]]=i; fac[i]=fac[i-1]*i%mod; } for(int i=1;i<=n+1;i++){ printf("%lld\n",((C(n+1,i)-C(n-d,i-1))%mod+mod)%mod); }
最新回复(0)