题面:
题意:
给定
T
T
T 组查询,每次询问
C
n
0
+
C
n
1
+
C
n
2
+
.
.
.
+
C
n
m
C_n^0+C_n^1+C_n^2+...+C_n^m
Cn0+Cn1+Cn2+...+Cnm。
题解:
我们设
S
n
m
=
C
n
0
+
C
n
1
+
C
n
2
+
.
.
.
+
C
n
m
S_n^m=C_n^0+C_n^1+C_n^2+...+C_n^m
Snm=Cn0+Cn1+Cn2+...+Cnm
有:
S
n
m
=
S
n
m
−
1
+
C
n
m
S_n^m=S_n^{m-1}+C_n^m
Snm=Snm−1+Cnm
S n m = 2 S n − 1 m − C n − 1 m S_n^m=2S_{n-1}^m-C_{n-1}^m Snm=2Sn−1m−Cn−1m
那么:
l
−
>
l
−
1
,
S
l
−
1
r
=
(
S
l
r
+
C
l
−
1
r
)
∗
i
n
v
2
l->l-1,S_{l-1}^r=(S_l^r+C_{l-1}^r)*inv2
l−>l−1,Sl−1r=(Slr+Cl−1r)∗inv2
l − > l + 1 , S l + 1 r = 2 S l r − C l r l->l+1,S_{l+1}^r=2S_l^r-C_l^r l−>l+1,Sl+1r=2Slr−Clr
r − > r − 1 , S l r − 1 = S l r − C l r r->r-1,S_l^{r-1}=S_l^r-C_l^r r−>r−1,Slr−1=Slr−Clr
r − > r + 1 , S l r + 1 = S l r + C l r + 1 r->r+1,S_l^{r+1}=S_l^{r}+C_l^{r+1} r−>r+1,Slr+1=Slr+Clr+1
可以快速转移。
莫队即可。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<bitset>
#include<map>
#include<unordered_map>
#include<set>
#define ui unsigned int
#define ll long long
#define llu unsigned ll
#define ld long double
#define pr make_pair
#define pb push_back
#define lc (cnt<<1)
#define rc (cnt<<1|1)
#define len(x) (t[(x)].r-t[(x)].l+1)
#define tmid ((l+r)>>1)
#define fhead(x) for(int i=head[(x)];i;i=nt[i])
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)>(y)?(y):(x))
using namespace std;
const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e18;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1.0);
const int hp=13331;
const int maxn=100100;
const int maxm=100100;
const int maxp=100100;
const int up=100100;
ll ans[maxn],res,inv2;
ll pos[maxn],fac[maxn],inv[maxn];
struct node
{
ll l,r,id;
}a[maxn];
ll mypow(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
void init(ll n)
{
inv2=mypow(2,mod-2);
ll t=sqrt(n);
for(int i=1;i<=n;i++)
pos[i]=(i-1)/t+1;
fac[0]=1;
for(ll i=1;i<=n;i++)
fac[i]=fac[i-1]*i%mod;
inv[n]=mypow(fac[n],mod-2);
for(ll i=n-1;i>=0;i--)
inv[i]=inv[i+1]*(i+1)%mod;
}
ll C(int n,int m)
{
if(n<0||m<0||m>n) return 0;
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
bool cmp(const node &a,const node &b)
{
if(pos[a.l]!=pos[b.l]) return pos[a.l]<pos[b.l];
else if(pos[a.l]&1) return a.r<b.r;
else return a.r>b.r;
}
void addl(int l,int r)//l-->l+1
{
res=(res*2-C(l,r)+mod)%mod;
}
void dell(int l,int r)//l-->l-1
{
res=(res+C(l,r))*inv2%mod;
}
void addr(int l,int r)//r-->r+1
{
res=(res+C(l,r))%mod;
}
void delr(int l,int r)//r-->r-1
{
res=(res-C(l,r)+mod)%mod;
}
int main(void)
{
ll n;
init(maxn-1);
scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&a[i].l,&a[i].r),a[i].id=i;
sort(a+1,a+n+1,cmp);
int ql=0,qr=0;
res=1;
//S(0,0)=C(0,0)=1;
/*以下也可。
int ql=1,qr=0;
res=1;
S(1,0)=C(1,0)=1;
*/
for(int i=1;i<=n;i++)
{
int nowl=a[i].l,nowr=a[i].r;
while(ql<nowl) addl(ql,qr),ql++;
while(ql>nowl) ql--,dell(ql,qr);
while(qr<nowr) qr++,addr(ql,qr);
while(qr>nowr) delr(ql,qr),qr--;
ans[a[i].id]=res;
}
for(int i=1;i<=n;i++)
printf("%lld\n",ans[i]);
return 0;
}