题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6333
题目:
题意:求C(n,0)+C(n,1)+……+C(n,m)的值。
思路:由于t和n数值范围太大,所以此题查询复杂度不能太高,由组合数的将前k项求和可以推出,从而可以转换成莫队的区间查询,将n当成l,m当成r即可。此题需要注意,对于求组合数得用o(1)的方法求,也就是阶乘相除的方法,对于分母我们得求逆元,因而借助欧拉定理。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <queue> 4 #include <stack> 5 #include <cmath> 6 #include <bitset> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 16 typedef long long ll; 17 typedef pair<ll, ll> pll; 18 typedef pair<ll, int> pli; 19 typedef pair<int, ll> pil;; 20 typedef pair<int, int> pii; 21 typedef unsigned long long ull; 22 23 #define lson i<<1 24 #define rson i<<1|1 25 #define bug printf("*********\n"); 26 #define FIN freopen("D://code//in.txt", "r", stdin); 27 #define debug(x) cout<<"["<<x<<"]" <<endl; 28 #define IO ios::sync_with_stdio(false),cin.tie(0); 29 30 const double eps = 1e-8; 31 const int mod = 1e9 + 7; 32 const int maxn = 1e5 + 7; 33 const double pi = acos(-1); 34 const int inf = 0x3f3f3f3f; 35 const ll INF = 0x3f3f3f3f3f3f3f; 36 37 int t, block; 38 ll sum; 39 ll a[maxn], b[maxn]; 40 41 struct node { 42 int l, r, id; 43 ll ans; 44 bool operator < (const node & x) const { 45 return (l - 1) / block == (x.l - 1) / block ? r < x.r : l < x.l; 46 } 47 }ask[maxn]; 48 49 ll Mod_Pow(ll x, ll n) { 50 ll res = 1; 51 while(n > 0) { 52 if(n & 1) res = res * x % mod; 53 x = x * x % mod; 54 n >>= 1; 55 } 56 return res; 57 } 58 59 void init() { 60 a[1] = 1; 61 for(int i = 2; i < maxn; i++) a[i] = a[i-1] * i % mod; 62 for(int i = 1; i < maxn; i++) b[i] = Mod_Pow(a[i], mod - 2); 63 } 64 65 ll C(int n, int m) { 66 if(n < 0 || m < 0 || m > n) return 0; 67 if(m == 0 || m == n) return 1; 68 return a[n] * b[n-m] % mod * b[m] % mod; 69 } 70 71 int main() { 72 //FIN; 73 init(); 74 scanf("%d", &t); 75 block = sqrt(maxn); 76 sum = 1; 77 for(int i = 1; i <= t; i++) { 78 scanf("%d%d", &ask[i].l, &ask[i].r); 79 ask[i].id = i; 80 } 81 sort(ask + 1, ask + t + 1); 82 for(int i = 1, l = 1, r = 0; i <= t; i++) { 83 while(l < ask[i].l) sum = (2 * sum - C(l++, r) + mod) % mod; 84 while(l > ask[i].l) sum = ((sum + C(--l, r)) * b[2]) % mod; 85 while(r < ask[i].r) sum = (sum + C(l, ++r)) % mod; 86 while(r > ask[i].r) sum = (sum - C(l, r--) + mod) % mod; 87 ask[ask[i].id].ans = sum; 88 } 89 for(int i = 1; i <= t; i++) { 90 printf("%lld\n", ask[i].ans); 91 } 92 return 0; 93 }