#include <iostream> #include <string> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <deque> #include <stack> #include <map> #define LL long long #define elif else if #define range(i,a,b) for(auto i=a;i<=b;++i) #define rerange(i,a,b) for(auto i=a;i>=b;--i) #define itrange(i,a,b) for(auto i=a;i!=b;++i) #define fill(arr,tmp) memset(arr,tmp,sizeof(arr)) using namespace std; int t,n,m,block[int(2e5)],interval,id=1; struct query{ int n,k,i; }Q[int(1e5+5)]; vector<query>ll[int(1e5+5)]; bool cmp(query a,query b){ return a.n<b.n; } const int mod=int(1e9+7); LL fac[int(1e5+5)],inv[int(1e5+5)],ans[int(1e5+5)]; LL q_pow(LL a,LL b){ if(b<0)return 0; LL ret=1; a%=mod; while(b){ ret=b&1?ret*a%mod:ret; b>>=1; a=a*a%mod; } return ret; } LL C(LL n,LL m){ if(n<m)return 0; return fac[n]*inv[m]%mod*inv[n-m]%mod; } void init(){ fac[0]=1; range(i,1,int(1e5))fac[i]=fac[i-1]*i%mod; inv[int(1e5)]=q_pow(fac[int(1e5)],mod-2); rerange(i,int(1e5-1),0)inv[i]=inv[i+1]*(i+1)%mod; interval=int(sqrt(1e5)); for(int i=1;i<=int(1e5);i+=interval,++id) for(int j=i;j<i+interval and j<=int(1e5);++j)block[j]=id; --id; scanf("%d",&t); range(i,1,t){ scanf("%d%d",&(Q+i)->n,&(Q+i)->k); (Q+i)->i=i; ll[block[Q[i].k]].push_back(Q[i]); } } void solve(){ range(i,1,id) if(ll[i].size()){ sort(ll[i].begin(),ll[i].end(),cmp); LL val=0,in=ll[i][0].n,ik=-1; range(j,0,ll[i].size()-1){ while(in<ll[i][j].n)val=((val<<1)+mod-C(in++,ik))%mod; while(ik<ll[i][j].k)val=(val+C(in,++ik))%mod; while(ik>ll[i][j].k)val=(val+mod-C(in,ik--))%mod; ans[ll[i][j].i]=val; } } range(i,1,t)printf("%lld\n",ans[i]); } int main() { init(); solve(); return 0; }
原文:https://www.cnblogs.com/Rhythm-/p/9403788.html