题目:
题目链接:Harvest of Apples [HDU 6333]
题解:
看完这个题,简单的推一下就知道题目让求的是
∑
i
=
0
m
(
n
i
)
\sum_{i=0}^m\tbinom{n}{i}
i=0∑m(in)
这样子的话,我们就来推一波式子,,,
F
(
n
,
m
)
=
(
n
0
)
+
(
n
1
)
+
⋅
⋅
⋅
+
(
n
m
)
F(n,m)=\tbinom{n}{0}+\tbinom{n}{1}+···+\tbinom{n}{m}
F(n,m)=(0n)+(1n)+⋅⋅⋅+(mn)
=
(
n
0
)
+
(
n
−
1
0
)
+
(
n
−
1
1
)
+
(
n
−
1
1
)
+
(
n
−
1
2
)
+
⋅
⋅
⋅
+
(
n
−
1
m
−
1
)
+
(
n
−
1
m
−
1
)
=
(
n
−
1
m
)
=\tbinom{n}{0}+\tbinom{n-1}{0}+\tbinom{n-1}{1}+\tbinom{n-1}{1}+\tbinom{n-1}{2}+···+\tbinom{n-1}{m-1}+\tbinom{n-1}{m-1}=\tbinom{n-1}{m}
=(0n)+(0n−1)+(1n−1)+(1n−1)+(2n−1)+⋅⋅⋅+(m−1n−1)+(m−1n−1)=(mn−1)
=
(
n
0
)
+
2
(
(
n
−
1
1
)
+
(
(
n
−
1
2
)
+
⋅
⋅
⋅
+
(
(
n
−
1
m
−
1
)
)
+
(
(
n
−
1
m
)
=\tbinom{n}{0}+2(\tbinom{n-1}{1}+(\tbinom{n-1}{2}+···+(\tbinom{n-1}{m-1})+(\tbinom{n-1}{m}
=(0n)+2((1n−1)+((2n−1)+⋅⋅⋅+((m−1n−1))+((mn−1)
由此,我们就可以得出:
F
(
n
−
1
,
m
)
=
F
(
n
,
m
)
+
(
n
−
1
m
)
2
F(n-1,m)=\frac{F(n,m)+\tbinom{n-1}{m}}{2}
F(n−1,m)=2F(n,m)+(mn−1)
因此,递推式就为:
F
(
n
,
m
)
=
2
∗
F
(
n
−
1
,
m
)
+
(
n
−
1
m
)
F(n,m)=2*F(n-1,m)+\tbinom{n-1}{m}
F(n,m)=2∗F(n−1,m)+(mn−1)
这样我们就可以求出
F
(
n
,
m
)
F(n,m)
F(n,m),但是呢,怎么
O
(
1
)
O(1)
O(1)求出
F
(
n
−
1
,
m
)
F(n-1,m)
F(n−1,m)或
F
(
n
,
m
−
1
)
F(n,m-1)
F(n,m−1)或
F
(
n
−
1
,
m
−
1
)
F(n-1,m-1)
F(n−1,m−1),这时候我们就想到了——————莫队啊!!!
(这样题就做完了,,,,,,,(今天不想发表情))
代码:
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#define LL long long
#define mod 1000000007
using namespace std;
inline LL read()
{
LL s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch<='9'&&ch>='0')s=s*10+ch-'0',ch=getchar();
return s*w;
}
const int sea=100010;
struct hit{int l,r,id,belong;}q[sea];
int T,block;
LL n,m,jc[sea],c[sea],ins[sea],ans[sea];
bool cmp(hit a,hit b)
{
if (a.belong!=b.belong) return a.l<b.l;
if (a.belong&1) return a.r<b.r; return a.r>b.r;
}//超推荐的奇偶判断,用在莫队里,直接降低一半的运行时间(否则我也不会T掉半天)
LL ksm(LL a ,LL b)
{
LL s=1;
while(b)
{
if(1&b) s=s*a%mod;
b>>=1; a=a*a%mod;
}
return s%mod;
}
void ycl()
{
jc[0]=1;jc[1]=1;ins[1]=1; ins[0]=1;
for(int i=1;i<=sea;i++) jc[i]=jc[i-1]*i%mod,ins[i]=ksm(jc[i],mod-2)%mod;
}
LL C(int a,int b)
{
if(a<b) return 0;
return jc[a]*ins[b]%mod*ins[a-b]%mod;
}
int main()
{
ycl();
scanf("%d",&T); block=sqrt(100000);
for(int i=1;i<=T;i++) q[i].r=read(),q[i].l=read(),q[i].id=i,q[i].belong=q[i].l/block;
sort(q+1,q+T+1,cmp);
int L=1,R=1;LL Ans=2;
for(int i=1;i<=T;i++)
{
while(L<q[i].l) Ans=(Ans+C(R,L+1))%mod,L++;
while(L>q[i].l) L--,Ans=(Ans-C(R,L+1)+mod)%mod;
while(R<q[i].r) R++,Ans=(2*Ans-C(R-1,L)+mod)%mod;
while(R>q[i].r) Ans=(Ans+C(R-1,L))*ins[2]%mod,R--;
ans[q[i].id]=Ans;
}
for(int i=1;i<=T;i++) printf("%d\n",ans[i]);
return 0;
}