hdu6333 多校第四场Problem B. Harvest of Apples(莫队)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6333

题意:求C(n,0)+C(n,1)+...+C(n,m)的和

思路:题解说可以莫队做,知道S(n,m)即可向附近项转化,想想也是,然后就写了下。(S(n,m)为前m项和)

先列出递推式:S(n+1,m)=2*(n,m)-C(n,m) ; S(n-1,m)=S(n,m)+C(n-1,m);

                         S(n,m+1)=S(n,m)+C(n,m+1) ; S(n,m-1)=S(n,m)-C(n,m)

这里还必须先预处理出组合数,否则不能O(1)转移。组合数取模又牵扯到逆元,就O(n)预处理出逆元,然后就直接莫队就行啦。

具体看代码

代码:

#include 
#define INF 0x3f3f3f3f
#define eps 1e-8
#define fuck(x) cout<<"<"<"< pii;
const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;


int pos[maxn];
LL ans[maxn];
LL sum;
struct query{
    int n,k,id;
}q[200005];
bool cmp(query a,query b){
    if (pos[a.n]==pos[b.n]) return a.k>= 1;
    }
    return ret;
}
void get(int n, int p) {
    fac[0] = 1;
    for (int i = 1; i <= n; ++i) {
        fac[i] = i * fac[i - 1] % p;
    }
    inv[n] = pow_mod(fac[n], p-2 , p);
    for (int i = n-1; i >= 0; --i) {
        inv[i] = inv[i + 1] * (i + 1) % p;
    }
}
LL c(int a,int b){
    return  1LL*fac[a] * inv[b] % mod * inv[a - b] % mod;
}
int main (){
    int n=100000,m;
    get(n,mod);
    scanf ("%d",&m);
    for (int i=1;i<=m;i++){
        scanf ("%d%d",&q[i].n,&q[i].k);
        q[i].id=i;
    }
    int block = (int)sqrt(n);
    for (int i=1;i<=n;i++) pos[i]=(i-1)/block+1;
    sort(q+1,q+1+m,cmp);
    int l=1,r=0;
    sum=1;
    for (int i=1;i<=m;i++){
        while (rq[i].n) sum=((sum+c(r-1,l))%mod*inv[2]%mod)%mod,r--;
        while (lq[i].k) sum=(sum-c(r,l)+mod)%mod,l--;
        ans[q[i].id]=sum;
    }
    for (int i=1;i<=m;i++){
        printf("%lld\n", ans[i]);
    }
}






 

你可能感兴趣的:(莫队)