vjudge :: Problem B. Harvest of Apples
阿新 • • 發佈:2021-07-15
http://acm.hdu.edu.cn/showproblem.php?pid=6333
題意: 求 C(0,n)+C(1,n)+...+C(m,n)
分析:
這道題,我們令s(m,n) =C(0,n)+C(1,n)+...+C(m,n)
那麼這道題就變成求各種s(m, n)
於是,莫隊這個演算法便可浮現在腦海裡!
我們現在需要用O(1)的時間轉移式子
s(m,n)=s(m-1,n)+C(m,n)
s(m,n)=s(m+1,n)-C(m+1,n)
S(m,n)=2*s(m,n-1)-C(m,n-1) ps:這個推導的方法,可以從“楊輝三角”中,輕鬆看出
S(m,n)=(s(m,n+1)+C(m,n))/2
ok,這道題AC了
接下來便是莫隊版版le
#include<bits/stdc++.h> using namespace std; #define re register int #define LL long long #define int long long const int N=1e5+5; const LL mo=1e9+7; int blo[N]; LL fac[N], inv[N], iv[N]; struct node{int a, b, id;}ask[N]; bool cmp(const node&x, const node&y) {if(blo[x.a] == blo[y.a]) return x.b < y.b; return blo[x.a] < blo[y.a]; } inline void init() { fac[0] = fac[1] = iv[1] = inv[1] = inv[0] = 1ll; for(re i=2, sq=sqrt(100000);i<=100000;++i) { iv[i] = mo - mo / i * iv[mo%i] % mo; inv[i] = inv[i-1] * iv[i] % mo; fac[i]= fac[i-1] * i % mo; blo[i] = (i-1) / sq + 1; } } inline LL getc(const int x, const int y) { if(x > y) return 0; return fac[y] * inv[x] % mo * inv[y-x] % mo; } int lt, rt; LL Tot; inline void Del1() // lt-- { Tot = ((Tot - getc(lt, rt)) % mo + mo) % mo; lt --; // printf("%lld\n", Tot); } inline void Add1() // lt++ { lt ++; Tot = ((Tot + getc(lt, rt)) % mo + mo) % mo; // printf("%lld\n", Tot); } inline void Del2() // rt-- { rt --; Tot = ((Tot + getc(lt, rt)) % mo * iv[2]) % mo; // printf("%lld\n", Tot); } inline void Add2() // rt++ { Tot = ((2 * Tot % mo - getc(lt, rt)) % mo + mo) % mo; rt ++; // printf("%lld\n", Tot); } LL ans[N]; signed main() { init(); int m; scanf("%lld",&m); for(re i=1;i<=m;++i) { scanf("%lld%lld",&ask[i].b,&ask[i].a); ask[i].id = i; } sort(ask+1, ask+1+m, cmp); lt=0; rt=0; Tot=1; for(re i=1;i<=m;++i) { while(rt < ask[i].b) Add2(); while(lt > ask[i].a) Del1(); while(rt > ask[i].b) Del2(); while(lt < ask[i].a) Add1(); ans[ask[i].id] = Tot; } for(re i=1;i<=m;++i) printf("%lld\n", ans[i]); }