码迷,mamicode.com
首页 > 系统相关 > 详细

AtCoder Grand Contest 023 C - Painting Machines

时间:2018-04-29 20:34:05      阅读:254      评论:0      收藏:0      [点我收藏+]

标签:操作   初始   cin   main   get   desc   return   names   void   

Description

一个长度为 \(n\) 的序列,初始都为 \(0\),你需要求出一个长度为 \(n-1\) 的排列 \(P\), 按照 \(1\)\(n\) 的顺序,每次把 \(P_i\)\(P_i+1\) 染成 \(1\),一个排列的价值为所有的位置都变成 \(1\) 的操作次数,求所有排列的价值和
题面

Solution

我们求出价值为 \(\lceil\frac{n}{2}\rceil\)\(n-1\) 的排列的方案数,然后分别算贡献就行了
操作最多 \(i\) 次的方案数是 \(f[i]\)
恰好 \(i\) 次的方案就是 \(f[i]-f[i-1]\)
\(f[i]=C_{i-1}^{n-1-i}\)
具体含义:可以看作是每次可以选择 \(+1,+2\) ,求构成 \(n-1\) 的方案数,我们先默认都 \(+1\),剩下就是选择 \(+0,+1\) 了,只要总共的 \(i-1\) 次操作中有 \(n-1-i\) 个选择了 \(+1\),就一定可以达到目标了

#include<bits/stdc++.h>
using namespace std;
template<class T>void gi(T &x){
    int f;char c;
    for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
    for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f;
}
const int N=1e6+10,mod=1e9+7;
int Fac[N],inv[N],n,f[N];
inline int C(int n,int m){
    return 1ll*Fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main(){
  freopen("pp.in","r",stdin);
  freopen("pp.out","w",stdout);
  cin>>n;
  int ans=0,li=(n+1)/2;
  Fac[0]=inv[0]=inv[1]=1;
  for(int i=1;i<=n;i++)Fac[i]=1ll*Fac[i-1]*i%mod;
  for(int i=2;i<=n;i++)inv[i]=(mod-1ll*(mod/i)*inv[mod%i]%mod)%mod;
  for(int i=2;i<=n;i++)inv[i]=1ll*inv[i]*inv[i-1]%mod;
  for(int i=li;i<n;i++)f[i]=1ll*C(i-1,n-1-i)*Fac[i]%mod*Fac[n-1-i]%mod;
  for(int i=n-1;i>=li;i--)f[i]=(f[i]-f[i-1]+mod)%mod;
  for(int i=n-1;i>=li;i--)ans=(ans+1ll*i*f[i])%mod;
  cout<<ans<<endl;
  return 0;
}

AtCoder Grand Contest 023 C - Painting Machines

标签:操作   初始   cin   main   get   desc   return   names   void   

原文地址:https://www.cnblogs.com/Yuzao/p/8971726.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!