zoukankan      html  css  js  c++  java
  • hdu6333 Problem B. Harvest of Apples(组合数+莫队)

    hdu6333 Problem B. Harvest of Apples

    题目传送门

    题意:

    求(0,n)~(m,n)组合数之和

    题解:

    C(n,m)=C(n-1,m-1)+C(n-1,m)   
    设 S(n,m)=C(n,0)+C(n,1)+C(n,2)+。。。+C(n,m)
    然后将S(n,m) 通过 第一个公式 拆项
    最后化简 变为 S(n,m)=2*S(n-1,m)-C(n-1,m);
    即:
    所以可以离线用莫队算法
    参考博客:链接1链接2

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    typedef long long ll;
    const int mod=1e9+7;
    const int N=1e5+5;
    
    /********组合数模板*********/
    ll pow_mod(ll a, ll b) {
        ll res = 1ll; a %= mod;
        while(b){
            if(b & 1) res = res * a % mod;
            a = a * a % mod;
            b >>= 1;
        } return res;
    }
    ll inv(ll a) { return pow_mod(a, mod-2); }
    ll F[N], Finv[N];//F是阶乘,Finv是逆元的阶乘
    void init() {
        F[0] = Finv[0] = 1ll;
        for(int i = 1; i < N; i ++){
            F[i] = F[i-1] * 1ll * (ll)i % mod;
            Finv[i] = Finv[i-1] * 1LL * inv(i) % mod;
        }
    } // O(n)预处理
    ll C(ll n, ll m) {
        if(m < 0 || m > n) return 0;
        return F[n] * 1LL * Finv[n - m] % mod * Finv[m] % mod;
    } // O(1)获得组合数C(n,m)
    /**************************/
    
    int block[N];
    ll res[N];
    struct mo
    {
        int n,m;
        int id,block;
        bool operator < (const mo &p) const{
          if(block==p.block) return n<p.n;
          else return block<p.block;
        }
    }s[N];
    int main()
    {
        int T;
        scanf("%d",&T);
        int len=sqrt(N+0.5);
        for(int i=0;i<T;i++)
        {
            scanf("%d %d",&s[i].n,&s[i].m);
            s[i].block=s[i].m/len;s[i].id=i;
        }
        sort(s,s+T);
        ll ans=1;
        init();
        int L=0,R=0;
        for(int i=0;i<T;i++)
        {
            int l=s[i].n,r=s[i].m;
            while(L>l) ans=((ans+C(L-1LL,R))%mod*Finv[2])%mod, L--;
            while(L<l) ans=(2*ans%mod-C(L,R)+mod)%mod, L++;
            while(R<r) ans=(ans+C(L,R+1))%mod, R++;
            while(R>r) ans=(ans-C(L,R)+mod)%mod, R--;
            res[s[i].id]=ans;
        }
        for(int i=0;i<T;i++)
            printf("%lld
    ",res[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    Linux编程之UDP SOCKET全攻略
    Java8 flatMap的sample
    swagger bug
    bash中的pasue
    树、二叉树、满二叉树、完全二叉树概念分清
    复习一下高中数学
    SpringBoot Junit Maven JaCoCo
    事务传播和隔离
    springboot swagger2 泛型踩坑记
    Code::Blocks debug程序
  • 原文地址:https://www.cnblogs.com/zhgyki/p/10388054.html
Copyright © 2011-2022 走看看