HDU6333 Harvest of Apples (杭电多校4B)
这莫队太强啦
先推公式S(n,m)表示从C(n, 0) 到 C(n, m)的总和
1.S(n, m) = S(n, m-1) + C(n, m) 这个直接可以转移得到
2.S(n, m) = S(n, m+1) - C(n, m+1) 通过变形就可以得到。
3.S(n, m) = C(n, 0) + C(n, 1) + C(n, 2) + ... + C(n, m)
= C(n-1, 0) + C(n-1, 0) + C(n-1, 1) + C(n-1, 1) + C(n-1, 2) + ... +C(n-1, m-1) + C(n-1, m)
= 2S(n-1, m) - C(n-1, m)
4.S(n, m) = (S(n+1, m) + C(n, m) ) / 2
然后求C(n, m)的时候打表存不下,所以就用C(n, m) = n!/ (m! * (n-m)!)
然后除法部分用逆元保证一下精度就可以了
然后就可以直接套莫队了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<map> #include<set> #include<ctime> #include<cmath> #include<stack> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define lowbit(x) (x & (-x)) typedef unsigned long long int ull; typedef long long int ll; const double pi = 4.0*atan(1.0); const int inf = 0x3f3f3f3f; const int maxn = 1e5+10; const int maxm = 10000007; const int mod = 1e9+7; using namespace std; int n, m, tol, T; int block; struct Node { int l; int r; int id; bool operator < (Node a) const { return l/block != a.l/block ? l/block < a.l/block : r < a.r; } }; Node node[maxn]; ll res[maxn]; ll fac[maxn]; ll inv[maxn]; ll ans; void init() { ans = 1; memset(res, 0, sizeof res); memset(node, 0, sizeof node); } ll fa_pow(ll a, ll b) { ll ans = 1; a %= mod; while(b) { if(b & 1) ans = ans * a % mod; a = a * a % mod; b >>= 1; } return ans % mod; } void handle() { fac[0] = 1; inv[0] = 1; for(int i=1; i<=100000; i++) { fac[i] = fac[i-1] * i; fac[i] %= mod; inv[i] = fa_pow(fac[i], mod-2); } } ll C(int n1, int m1) { if(m1 > n1) return 0; ll ans = fac[n1] * inv[m1] % mod * inv[n1-m1] % mod; return ans; } int main() { init(); handle(); scanf("%d", &n); block = sqrt(n); for(int i=1; i<=n; i++) scanf("%d%d", &node[i].l, &node[i].r), node[i].id = i; sort(node+1, node+1+n); int L = 1; int R = 0; for(int i=1; i<=n; i++) { while(L > node[i].l) { L--; ans = (ans + C(L, R)) % mod * inv[2] % mod; } while(L < node[i].l) { ans = (ans * 2 % mod - C(L, R)) % mod + mod; ans %= mod; L++; } while(R < node[i].r) { R++; ans = (ans + C(L, R)) % mod; } while(R > node[i].r) { ans = (ans - C(L, R) % mod) + mod; ans %= mod; R--; } res[node[i].id] = ans; } for(int i=1; i<=n; i++) printf("%I64d\n", res[i]); return 0; }