Problem B. Harvest of Apples(莫队+数学)

Problem Description
There are n apples on a tree, numbered from 1 to n.
Count the number of ways to pick at most m apples.
 
Input
The first line of the input contains an integer T (1T105) denoting the number of test cases.
Each test case consists of one line with two integers n,m (1mn105).
 
Output
For each test case, print an integer representing the number of ways modulo 109+7.
 
Sample Input
2 5 2 1000 500
 
Sample Output
16 924129523
 
SOLUTION:
神仙题目
 
设s (n,m) 为所要求的值

发现不同的 s 之间可以互相的转移

应该可以联想到莫队离线

CODE:

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
using namespace std;
#define ll long long
#define mod 1000000007

const int maxn =100000+5;

ll ans[maxn],fac[maxn]={1,1},inv[maxn]={1,1},f[maxn]={1,1},len;

int T;

ll cal(ll a,ll b)  //求组合数
{
    if(b>a)
        return 0;
    return fac[a]*inv[b]%mod*inv[a-b]%mod;
}

void init()
{
    for(int i=2; i<=maxn-1; i++)
    {
        fac[i]=fac[i-1]*i%mod;//阶乘
        f[i]=(mod-mod/i)*f[mod%i]%mod;//逆元
        inv[i]=inv[i-1]*f[i]%mod;//逆元的阶乘
    }
}
struct Query
{
    ll L,R,block;
    int ID;
    Query(){};
    Query(ll l, ll r, int ID) :L(l), R(r), ID(ID){
        block=l/len;
    }
   bool operator<(const Query rhs)const{
        if(block ==rhs.block)
          {
             if(block&1) return R>rhs.R;
             else return R<rhs.R;
          }
        return block <rhs.block;
   }
}queries[maxn];


int main()
{
    len=sqrt(maxn);///块长度
    init();

    scanf("%d",&T);
    for(int i=1; i<=T; i++)
    {
        ll l,r;
        scanf("%lld %lld",&l,&r);
         queries[i]=Query(l,r,i);
    }
    sort(queries+1,queries+T+1);

    int l=1 ,r=1;
    ll val=2;

    for(int i=1; i<=T; i++)
    {


      while(l<queries[i].L)
      {

        val=(2ll*val%mod+mod-cal(l,r))%mod;
        l++;

      }

       while(l>queries[i].L)
      {
          --l;
          val=(val+cal(l,r))%mod *f[2]%mod;

      }

    while(r<queries[i].R)
      {
          val=(val+cal(l,++r))%mod;

      }

      while(r>queries[i].R)
      {
          val=(val-cal(l,r--))%mod;
          val+=mod;
          val%=mod;

      }

        ans[queries[i].ID]=val;
    }

    for(int i=1; i<=T; i++)
        printf("%lld
",ans[i]);

    return 0;
}

  

 
 
 
 
原文地址:https://www.cnblogs.com/zhangbuang/p/11293938.html