HDU 6333 Problem B. Harvest of Apples(莫队算法)

题目描述:

给出T组n和m(1<=T<=1e5, 1<=m<=n<=1e5)。

\sum_{i=0}^{m}C_{n}^{i}

题目分析:

记:S_{n}^{i}=\sum_{i=0}^{m}C_{n}^{i}

通过杨辉三角得出:

S_{L}^{R}=S_{L}^{R-1}+C_{L}^{R}          ==           S_{L}^{R}=S_{L}^{R+1}-C_{L}^{R+1}

S_{L}^{R}=2*S_{L-1}^{R}-C_{L-1}^{R}      ==      S_{L}^{R}=(S_{L+1}^{R}+C_{L}^{R})/2

所以只需要求出1e5以内的全部组合数就可以进行任意移动了,组合数模板:

const int N = 1e7;		//复杂度O(n)
const ll mod = 1e9 + 7;
int F[N], Finv[N], inv[N];//F是阶乘,Finv是阶乘的逆元
//X 关于 mod 的逆元为 x^(mod - 2);
void init(){
	F[0] = Finv[0] = inv[1] = 1;
	for (register int i = 2; i < N; i++)
		inv[i] = (mod - mod / i) * 1ll * inv[mod % i] % mod;
	for (register int i = 1; i < N; i++){
		F[i] = F[i - 1] * 1ll * i % mod;
		Finv[i] = Finv[i - 1] * 1ll * inv[i] % mod;
	}
}
int comb(int n, int m){///comb(n, m)就是C(n, m)
	if (m < 0 || m > n) return 0;
	return F[n] * 1ll * Finv[n - m] % mod * Finv[m] % mod;
}

AC代码:

#include 
#define ll long long
using namespace std;
const int INF=0x3f3f3f3f;
const int N = 1e5+7;        //复杂度O(n)
const ll mod = 1e9 + 7;
int F[N], Finv[N], inv[N];
void init(){
    F[0] = Finv[0] = inv[1] = 1;
    for (register int i = 2; i < N; i++)
        inv[i] = (mod - mod / i) * 1ll * inv[mod % i] % mod;
    for (register int i = 1; i < N; i++){
        F[i] = F[i - 1] * 1ll * i % mod;
        Finv[i] = Finv[i - 1] * 1ll * inv[i] % mod;
    }
}
int comb(int n, int m){///comb(n, m)就是C(n, m)
    if (m < 0 || m > n) return 0;
    return F[n] * 1ll * Finv[n - m] % mod * Finv[m] % mod;
}

inline int read(){//读入整数
    int k = 0, f = 1; char c = getchar();
    while (c<'0' || c>'9')c == '-' && (f = -1), c = getchar();
    while ('0' <= c&&c <= '9')k = k * 10 + c - '0', c = getchar();
    return k*f;
}
struct query{
    int l,r,id,ans;
}q[100005];
int m;
bool cmp1(query a,query b){
    if(a.l/317==b.l/317)
        return a.rR){//之前以为注释部分不加进行移动会出错,其实能AC
//            if(L==R){
//                tmp=comb(L,R);
//                S=(2*S-tmp+mod)%mod;
//                L++;
//            }
            R++;
            tmp=comb(L,R);
            S=(S+tmp)%mod;
        }
        while(q[i].lL){
            tmp=comb(L,R);
            S=(2*S-tmp+mod)%mod;
            L++;
        }
        q[i].ans=S;
    }
}
int main(){
    init();
    m=read();
    for(int i=0;i

 

你可能感兴趣的:(莫队)