HDU - 6333 Harvest of Apples

题意:

  T次询问,每次给出n,m。求sigma(k:0->m)C(n, k)。

题解:

  用离线莫队来做。

  令S(n,m) = sigma(k:0->m)C(n, k)。

  S(n+1, m) = 2S(n, m) - C(n, m)   S(n-1, m) = (S(n, m) + C(n-1, m)) / 2

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

#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
const int N = 1e5+10;
int t;
int blk;
int blg[N];
int fac[N], inv[N], tmp[N];
int l, r, now;
int ans[N];
struct ask {
    int l, r, id;
    bool operator < (const ask &a) {
        return blg[l] == blg[a.l] ? r < a.r : l < a.l;
    }
}q[N];
int C(int n, int m) {
    int res = 1ll*fac[n]*inv[m]%mod;
    res = 1ll*res*inv[n-m]%mod;
    return res;
}
void update(int k, int t) {
    if(t == 1) {
        if(~k) now = (2ll*now-C(l, r)+mod)%mod;
        else now = 1ll*(now+C(l-1, r))*tmp[2]%mod;
    }
    else {
        if(~k) now = (now+C(l, r))%mod;
        else now = (now-C(l, r)+mod)%mod;
    }
}
int main() {
    fac[0] = fac[1] = tmp[1] = inv[0] = inv[1] = 1;
    for(int i = 2; i < N; i++) {
        fac[i] = 1ll*fac[i-1]*i%mod;
        tmp[i] = 1ll*(mod-mod/i)*tmp[mod%i]%mod;
        inv[i] = 1ll*inv[i-1]*tmp[i]%mod;
    }
    scanf("%d", &t);
    int up = 0;
    for(int i = 1; i <= t; i++) {
        scanf("%d%d", &q[i].l, &q[i].r);
        up = max(up, q[i].r);
        q[i].id = i;
    }
    blk = sqrt(t);
    for(int i = 1; i <= up; i++) blg[i] = (i-1)/blk;
    sort(q+1, q+t+1);
    now = 1;
    l = 0, r = 0;
    for(int i = 1; i <= t; i++) {
        while(r > q[i].r) update(-1, 0), r--;
        while(l < q[i].l) update(1, 1), l++;
        while(l > q[i].l) update(-1, 1), l--;
        while(r < q[i].r) r++, update(1, 0);
        ans[q[i].id] = now;
    }
    for(int i = 1; i <= t; i++) printf("%d\n", ans[i]);
}
View Code

 

  

posted @ 2018-08-02 10:32  Pneuis  阅读(251)  评论(0编辑  收藏  举报