高橋君 AT_tenka1_2014_final_d 莫队 组合数求和

和上一题类似不过这道题不能再使用Lucas定理了。

\(m\)组询问 \(\sum_{i=0}^kC(n,i)\%\ 1e9+7,n,m,k\le 100000\)

这是一个很经典的莫队求组合数的和的问题。

因为有两个指针\(l,r\)

显然需要处理四种情况:

\(l,r->l+1,r\)此时加上\(C(r,l+1)\)即可。

\(l,r->l-1,r\)此时减去\(C(r,l)\)即可。

\(l,r->l,r+1\)此时加上\(\sum_{i=0}^{l-1}C(r,i)\)即可。

\(l,r->l,r-1\)此时减去\(\sum_{i=0}^{l-1}C(r-1,i)\)即可。

//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define inf 100000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x)
#define putl_(x) printf("%lld ",x)
#define get(x) x=read()
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(int i=p;i<=n;i+=1)
#define fep(n,p,i) for(int i=n;i>=p;--i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define pii pair<int,int>
#define mk make_pair
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define ui unsigned
#define sq sqrt
#define x(w) t[w].x
#define r(w) t[w].r
#define id(w) t[w].id
#define R(w) s[w].r
#define yy p<<1|1
#define zz p<<1
#define sum(w) t[w].sum
#define mod 1000000007
#define sc(A) scanf("%d",&A)
#define scl(A) scanf("%lld",&A)
#define scs(A) scanf("%s",A);
#define put(A) printf("%d\n",A)
#define min(x,y) (x>=y?y:x)
#define max(x,y) (x>=y?x:y)
#define sub(x,y) (x-y<0?x-y+mod:x-y)
#define uint unsigned int
using namespace std;
const int MAXN=100010,G=3;
int T,B;
int cnt[MAXN];
int fac[MAXN],inv[MAXN];
inline int ksm(int b,int cc)
{
	int cnt=1;
	while(cc)
	{
		if(cc&1)cnt=(ll)cnt*b%mod;
		b=(ll)b*b%mod;cc=cc>>1;
	}
	return cnt;
}
inline int C(int n,int m){return m>n?0:(ll)fac[n]*inv[m]%mod*inv[n-m]%mod;}
struct wy
{
	int l,r,id;
}t[MAXN];
inline int cmp(wy a,wy b){return a.l/B==b.l/B?a.l/B&1?a.r>b.r:a.r<b.r:a.l<b.l;}
//inline int cmp(wy a,wy b){return a.l/B==b.l/B?a.r<b.r:a.l<b.l;}
int main()
{
	freopen("1.in","r",stdin);
	sc(T);
	fac[0]=1;int maxx=100000;B=(int)sqrt(maxx*1.0);
	rep(1,maxx,i)fac[i]=(ll)fac[i-1]*i%mod;
	inv[maxx]=ksm(fac[maxx],mod-2);
	fep(maxx-1,0,i)inv[i]=(ll)inv[i+1]*(i+1)%mod;
	rep(1,T,i)
	{
		sc(t[i].r);
		sc(t[i].l);
		t[i].id=i;
	}
	sort(t+1,t+1+T,cmp);
	int L=0,R=0,ans=1,inv2=(mod+1)>>1;
	rep(1,T,i)
	{
		while(R>t[i].r)
		{
			--R;
			ans=(ans+C(R,L))*(ll)inv2%mod;
		}
		while(R<t[i].r)
		{
			ans=(ans*2%mod-C(R,L)+mod)%mod;
			++R;
		}
		while(L>t[i].l)
		{
			ans=(ans-C(R,L)+mod)%mod;
			--L;
		}
		while(L<t[i].l)
		{
			++L;
			ans=(ans+C(R,L))%mod;
		}
		cnt[t[i].id]=ans;
	}
	rep(1,T,i)put(cnt[i]);
	return 0;
}
posted @ 2023-09-04 22:35  chdy  阅读(14)  评论(0编辑  收藏  举报