题意
给定 \(n, k\),求
\[\sum\limits_{i = 0}^{k}\dbinom{n}{i} \]多测,\(1 \le n, k, T \le 10^5\)。
题解
可以考虑使用莫队求解,下文讲述如何移动指针。
\(n \rightarrow n + 1\)
根据杨辉三角递推式 \(\dbinom{n}{m} = \dbinom{n - 1}{m} + \dbinom{n - 1}{m - 1}\) 可以得出
\[\begin{aligned} F(n + 1, m) &= \sum\limits_{i = 0}^{m} \dbinom{n + 1}{i} \\ &= \sum\limits_{i = 0}^{m} \left(\dbinom{n}{i} + \dbinom{n}{i - 1}\right) \\ &= 2\sum\limits_{i = 0}^{m} \dbinom{n}{i} - \dbinom{n}{m} \\ &= 2 \cdot F(n, m) - \dbinom{n}{m} \end{aligned}\]\(m \rightarrow m + 1\)
\[\begin{aligned} F(n, m + 1) &= \sum\limits_{i = 0}^{m + 1} \dbinom{n}{i} \\ &= \sum\limits_{i = 0}^{m} \dbinom{n}{i} + \dbinom{n}{m + 1}\\ &= F(n, m) + \dbinom{n}{m + 1} \end{aligned}\]这部分的复杂度为 \(\mathcal{O}(n \sqrt{n})\)。
总复杂度 \(\mathcal{O}(n \sqrt{n})\),可以通过本题。
Code
#include <bits/stdc++.h>
typedef long long valueType;
typedef std::vector<valueType> ValueVector;
typedef ValueVector::iterator iterator;
typedef std::vector<iterator> IteratorVector;
constexpr valueType MOD = 1e9 + 7;
template<typename T1, typename T2, typename T3 = valueType>
void Inc(T1 &a, T2 b, const T3 &mod = MOD) {
a = a + b;
if (a >= mod)
a -= mod;
}
template<typename T1, typename T2, typename T3 = valueType>
void Dec(T1 &a, T2 b, const T3 &mod = MOD) {
a = a - b;
if (a < 0)
a += mod;
}
template<typename T1, typename T2, typename T3 = valueType>
T1 mul(T1 a, T2 b, const T3 &mod = MOD) {
return (long long) a * b % mod;
}
template<typename T1, typename T2, typename T3 = valueType>
void Mul(T1 &a, T2 b, const T3 &mod = MOD) {
a = (long long) a * b % mod;
}
template<typename T1, typename T2, typename T3 = valueType>
T1 pow(T1 a, T2 b, const T3 &mod = MOD) {
T1 result = 1;
while (b > 0) {
if (b & 1)
Mul(result, a, mod);
Mul(a, a, mod);
b = b >> 1;
}
return result;
}
namespace UU {
valueType N, M;
ValueVector Fact, InvFact, belong, ans;
valueType C(valueType n, valueType m) {
if (n < m)
return 0;
return mul(Fact[n], mul(InvFact[m], InvFact[n - m]));
}
struct Query {
valueType n, m, id;
Query(valueType n, valueType m, valueType id) : n(n), m(m), id(id) {}
friend bool operator<(Query const &left, Query const &right) {
if (belong[left.n] != belong[right.n])
return belong[left.n] < belong[right.n];
return left.m < right.m;
}
};
std::vector<Query> query;
void init(valueType n) {
N = n;
M = 0;
Fact.resize(N + 1);
InvFact.resize(N + 1);
belong.resize(N + 1);
valueType block = std::ceil(std::sqrt((double) N));
for (valueType i = 1; i <= N; ++i)
belong[i] = (i - 1) / block + 1;
Fact[0] = 1;
for (valueType i = 1; i <= N; ++i)
Fact[i] = mul(Fact[i - 1], i);
InvFact[N] = pow(Fact[N], MOD - 2);
for (valueType i = N - 1; i >= 0; --i)
InvFact[i] = mul(InvFact[i + 1], i + 1);
}
void add(valueType id, valueType n, valueType m) {
query.emplace_back(n, m, id);
}
constexpr valueType Inv2 = (MOD + 1) / 2;
void solve() {
std::sort(query.begin(), query.end());
M = (valueType) query.size();
ans.resize(M);
valueType nowN = 0, nowM = 0;
valueType Ans = 1;
for (auto const &iter : query) {
while (nowM < iter.m) {
++nowM;
Inc(Ans, C(nowN, nowM));
}
while (nowM > iter.m) {
Dec(Ans, C(nowN, nowM));
--nowM;
}
while (nowN < iter.n) {
Mul(Ans, 2);
Dec(Ans, C(nowN, nowM));
++nowN;
}
while (nowN > iter.n) {
--nowN;
Inc(Ans, C(nowN, nowM));
Mul(Ans, Inv2);
}
ans[iter.id] = Ans;
}
}
void output() {
for (auto const &iter : ans)
std::cout << iter << std::endl;
}
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
valueType M;
std::cin >> M;
UU::init(1e5);
for (valueType i = 0; i < M; ++i) {
valueType n, m;
std::cin >> n >> m;
UU::add(i, n, m);
}
UU::solve();
UU::output();
return 0;
}
标签:nowM,nowN,dbinom,高橋,题解,valueType,Ans,mod
From: https://www.cnblogs.com/User-Unauthorized/p/solution-AT_tenka1_2014_final_d.html