• codeforces 816 D. Karen and Test(逆元+思维+组合数)


    题目链接:http://codeforces.com/contest/816/problem/D

    题解:显然一看到这题应该会想到是有什么规律的于是多写几项就会发现偶数列之间是有关系的。

    满足a[i][j]=a[i-2][j]+a[i-2][j+2],于是递推到最后第2列a[2][0],a[2][1]就可以用最早出现的偶数列来求的,最后是加还是减只要看n就行了。

    由于a[2][0]是有几个最早出现的偶数列的奇数项求的,而且这些奇数项选择的次数符合二项式分布(这个可以通过花一下杨辉三角理解一下)。

    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <cstdio>
    #define mod 1000000007
    using namespace std;
    const int M = 2e5 + 10;
    typedef long long ll;
    ll anum[M] , bnum[M] , up[M] , down[M];
    ll inv(ll a) {
        return a == 1 ? 1 : (ll)(mod - mod / a) * inv(mod % a) % mod;
    }
    //ll C(ll n , ll m)
    //{
    //    if(m < 0)return 0;
    //    if(n < m)return 0;
    //    if(m > n-m) m = n-m;
    //    ll up = 1, down = 1;
    //    for(ll i = 0 ; i < m ; i++){
    //        up = up * (n-i) % mod;
    //        down = down * (i+1) % mod;
    //    }
    //    return up * inv(down) % mod;
    //}//原先利用逆元的算法,但是这里直接求会超时与处理一下up和down就行。
    int main() {
        int n;
        scanf("%d" , &n);
        for(int i = 0 ; i < n ; i++) scanf("%lld" , &anum[i]) , bnum[i] = anum[i];
        if(n == 1) {printf("%lld
    " , anum[0]); return 0;}
        if(n & 1) {
            n--;
            int flag = 1;
            for(int i = 0 ; i < n ; i++) {
                if(flag) anum[i] = (bnum[i] + bnum[i + 1]) % mod;
                else anum[i] = (bnum[i] - bnum[i + 1] + mod) % mod;
                flag ^= 1;
            }
        }
        n = n / 2 - 1;
        ll ans1 = 0 , ans2 = 0;
        up[0] = 1 , down[0] = 1;
        for(int i = 1 ; i <= n / 2 ; i++) up[i] = up[i - 1] * (n - i + 1) % mod , down[i] = down[i - 1] * i % mod;
        for(int i = n / 2 + 1 ; i <= n ; i++) up[i] = up[n - i] , down[i] = down[n - i];
        for(int i = 0 ; i <= n ; i++) {
            ans1 += anum[2 * i] * (up[i] * inv(down[i]) % mod) % mod;
            ans1 %= mod;
            ans2 += anum[2 * i + 1] * (up[i] * inv(down[i]) % mod) % mod;
            ans2 %= mod;
        }
        if(n % 2) ans1 = (ans1 - ans2 + mod) % mod;
        else ans1 = (ans1 + ans2) % mod;
        printf("%lld
    " , ans1);
        return 0;
    }
    
    
  • 相关阅读:
    【使用教程】CMDer,Window下CMD的替代者
    什么是数据仓库?
    【大话存储】学习笔记(八),数据保护
    分布式与集群
    【大话存储】学习笔记(五),以太网
    【廖雪峰】Python
    【大话存储】学习笔记(7章), OSI模型
    KVM计算虚拟化原理,偏基础
    DevOps
    H3C CAS(云管理平台)介绍
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/7054283.html
Copyright © 2020-2023  润新知