HDU 6333 Problem B. Harvest of Apples (莫队算法+数学思维)

Problem B. Harvest of Apples

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2073    Accepted Submission(s): 804


 

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 (1≤T≤105) denoting the number of test cases.
Each test case consists of one line with two integers n,m (1≤mn≤105).

 

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

 

Source

2018 Multi-University Training Contest 4

 

Recommend

chendu   |   We have carefully selected several similar problems for you:  6343 6342 6341 6340 6339 

 

#include<iostream>
#include<algorithm>
#include<string>
#include<map>//int dx[4]={0,0,-1,1};int dy[4]={-1,1,0,0};
#include<set>//int gcd(int a,int b){return b?gcd(b,a%b):a;}
#include<vector>
#include<cmath>
#include<stack>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#define ll long long
#define MAX 1000000000
#define ms memset
using namespace std;
const int mod=1e9+7;
const int maxn=1e5+5;
/*
题目大意:很简洁,求组合数,
观察数据发现查询的数量特别多,
就是说可以预处理查询来简化复杂度。
不难想到莫队算法。
莫队算法也有要求的,要求在O(1)时间内完成
(n,m)到(n-1,m)或(n,m-1)的转移。

那么对于这题,考验点数学思维。
S(n,m)=2*S(n-1,m)-C(n-1,m)
S(n,m)=S(n,m-1)+C(n,m)
莫队转移时注意点即可,其他的没有什么特别的。

这题这代码过不了,但是自己想的所有样例都没问题,
头疼,思路大致是对的,欢迎点出错误。
*/
ll Powmod(ll a,ll b)
{
    ll t=1;
    while(b)
    {
        if(b&1) t=1ll*t*a%mod;
        a=1ll*a*a%mod;
        b>>=1;
    }
    return t;
}

ll jie[maxn+1],inv[maxn+1];///阶乘,和阶乘的逆元
void init()
{
    jie[0]=jie[1]=1;
    for(int i=2;i<=maxn;i++) jie[i]=(1ll*jie[i-1]*i)%mod;
    inv[maxn]=Powmod(jie[maxn],mod-2);
    for(int i=maxn-1;~i;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
}

ll C(ll n, ll m)
{
    return jie[n]*inv[m] %mod * inv[n-m] %mod;
}

struct node
{
    ll l,r,id;
    node(){}
};
node q[maxn];

int blocks;
bool cmp(node x,node y)
{
    if(x.r/blocks==y.r/blocks) return x.l<y.l;
    return x.r<y.r;
}

int main()
{
    init();
    int mx=100000;

    int t;scanf("%d",&t);

    for(int i=0;i<t;i++)
    {
        scanf("%lld%lld",&q[i].r,&q[i].l);
        q[i].id=i;
    }

    blocks=sqrt(mx);
    sort(q,q+t,cmp);

    ll ans[maxn],l=-1,r=0,res=0;
    for(int i=0;i<t;i++)
    {
        ///cout<<q[i].r<<" "<<q[i].l<<endl;
        while(r<q[i].r) res=( (res+res)%mod-C(r++,l)+mod )%mod;
        while(r>q[i].r) res=(res+C(--r,l))/2,res%=mod;
        while(l<q[i].l) res=( res+C(r,++l) )%mod;
        while(l>q[i].l) res=(res-C(r,l--)+mod)%mod;
        ans[q[i].id]=res;
    }
    for(int i=0;i<t;i++) printf("%lld\n",ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37451344/article/details/81369146
今日推荐