Codeforces Round #419 (Div. 1) B. Karen and Test(组合数)

来源:互联网 发布:fcn caffe windows 编辑:程序博客网 时间:2024/05/16 06:26

题目链接:http://codeforces.com/contest/815/problem/B


题解:

写一写规律,发现就是一个针对奇偶项分开的二项式展开后的系数。


对于a1,a2,a3,a4这个序列


无论第一个填加号还是减号,进行两步处理后,都可以变成


a1+a3,a2+a4这两项,所以发现这就是一个杨辉三角的展开后的形式。然后利用组合数分别处理奇偶项即可。


然后对于n为奇数的时候,将n处理为偶数,然后注意合并奇项和偶项时候的加减号的处理


代码:

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int MAXN=2e5+5;const int MOD=1e9+7;ll a[MAXN];ll b[MAXN];ll fac[MAXN];ll qpow(ll a,ll b){ll ans=1;a%=MOD;    for(ll i=b;i;i>>=1,a=a*a%MOD)        if(i&1)ans=ans*a%MOD;    return ans;}ll C(ll n,ll m){    if(m>n||m<0)return 0;    ll s1=fac[n],s2=fac[n-m]*fac[m]%MOD;    return s1*qpow(s2,MOD-2)%MOD;//费马小定理求逆元 }void init(){fac[0]=1;for(int i=1;i<MAXN;i++)//阶乘打表     fac[i]=fac[i-1]*i%MOD;}int main(){//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);int n;init();scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%lld",&a[i]);}if(n==1){return 0*printf("%lld\n",a[1]%MOD);}if(n&1){int op=1;n--;for(int i=1;i<=n;i++){b[i]=a[i]+(op*a[i+1]);op=-op;}for(int i=1;i<=n;i++){a[i]=b[i];}}ll s=0,t=0;for(int i=1;i<=n;i++){if(i&1){s=(s+C(n/2-1,i/2)*a[i]%MOD)%MOD;}else{t=(t+C(n/2-1,i/2-1)*a[i]%MOD)%MOD;}}ll ans;if(!((n/2)&1)){ans=((s-t)%MOD+MOD)%MOD;}else{ans=((s+t)%MOD+MOD)%MOD;}printf("%lld\n",ans);}



阅读全文
1 0