HDU-6333 Problem B. Harvest of Apples(莫队+组合数)

题目:求C(n,0)+C(n,1)+C(n,2)+.......+C(n,m)

思路:S(l,r)=S(l,r-1)+C(l,r)         S(l,r)=2*S(l-1,r)-C(l-1,r);(想想杨辉三角就容易看出来了)

          S(l,r)=S(l,r+1)-C(l,r+1)      S(l,r)=(S(l+1,r)-C(l,r))/2; (由上面得到)

预处理阶乘逆元,然后莫队搞一下。

不告诉你(l,r)你就不知道当作区间的题来做???思维定式了要。。我好菜。。。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int N=1e5;
const ll mod=1e9+7;
ll fac[maxn],inv[maxn];
ll qmod(ll x,ll p)
{
    ll ans=1;
    while(p)
    {
        if(p&1) ans=ans*x%mod;
        x=x*x%mod;
        p>>=1ll;
    }
    return ans;
}
void init()
{
    fac[0]=1ll;
    for(int i=1;i<=N;i++)
        fac[i]=1ll*i*fac[i-1]%mod;
    inv[N]=qmod(fac[N],mod-2);
    for(int i=N-1;i>=0;i--)
        inv[i]=1ll*(i+1)*inv[i+1]%mod;
}
ll C(int n,int m)
{
    if(m>n) return 0ll;
    return fac[n]*inv[n-m]%mod*inv[m]%mod;
}

struct node{
    int l,r,id;
}s[maxn];
int n,block[maxn],T;
ll ans[maxn];
bool cmp(const node &a,const node &b)
{
    if(block[a.l]==block[b.l]) return a.r<b.r;
    return block[a.l]<block[b.l];
}

int main()
{
    init();
    ll _2=qmod(2ll,mod-2ll);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&s[i].l,&s[i].r);
        s[i].id=i;
    }
    int t=(int)sqrt(1.0*n);
    for(int i=0;i<=n;i++)
        block[i]=i/t;

    sort(s+1,s+n+1,cmp);
    int l=1,r=0;
    ll sum=1ll;
    for(int i=1;i<=n;i++)
    {
        while(r<s[i].r)
        {
            r++;
            sum=(sum+C(l,r))%mod;
        }
        while(r>s[i].r)
        {
            sum=(sum-C(l,r)+mod)%mod;
            r--;
        }
        while(l<s[i].l)
        {
            sum=(2ll*sum%mod-C(l,r)+mod)%mod;
            l++;
        }
        while(l>s[i].l)
        {
            l--;
            sum=(sum+C(l,r))%mod*_2%mod;
        }
        ans[s[i].id]=sum;
    }
    for(int i=1;i<=n;i++)
        printf("%lld\n",ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/dllpXFire/article/details/81348846