問題の説明
ある n個 の番号が付けツリー上のリンゴ、 1 に nが。
選択する方法の数カウント 、最大で m個の りんごを。
選択する方法の数カウント 、最大で m個の りんごを。
入力
入力の最初の行は整数含ま T (1 ≤ T ≤ 10 5 ) テストケースの数を示すが。
各テストケースは、1~2の整数を持つ線で構成され 、N 、M (1 ≤ Mの≤ N ≤ 10 5 )。
各テストケースは、1~2の整数を持つ線で構成され 、N 、M (1 ≤ Mの≤ N ≤ 10 5 )。
出力
各テストケースのために、いくつかの方法を表す整数モジュロ印刷 10 9 + 7。
サンプル入力
2 5 2 1000 500
サンプル出力
16 924129523
溶液:
不滅のタイトル
集合S(N、M)は、所望の値であります
それぞれが異なる発見sの間で転送することができます
あるべき Moのチームをオフラインに関連付けることが可能
コード:
書式#include <iostreamの> 書式#include <stdio.hに> 書式#include <math.h>の 書式#include <stdlib.h>に含ま 書式#include <アルゴリズム> 書式#include <キュー> 書式#include <ベクトル> 書式#include <マップ> 名前空間stdを使用。 #defineは長い長いっ #defineモッズ1000000007 const int型MAXN = 100000 + 5。 LL ANS [MAXN]、FAC [MAXN] = {1,1}、INV [MAXN] = {1,1}、[MAXN] F = {1,1}、lenの; int型T; LL CAL(LL bの、LL)//組み合わせの数を見つけます { (B> A)の場合 0を返します。 FAC戻り[A] * [B]%MOD *のINV INV [AB]%MOD。 } init()メソッドを無効に { 以下のために(INT I = 2; I <= MAXN-1; iは++) { FAC [i]は= FAC [I-1] *%Vとして; //阶乘 f[i]=(mod-mod/i)*f[mod%i]%mod;//逆元 inv[i]=inv[i-1]*f[i]%mod;//逆元的阶乘 } } struct Query { ll L,R,block; int ID; Query(){}; Query(ll l, ll r, int ID) :L(l), R(r), ID(ID){ block=l/len; } bool operator<(const Query rhs)const{ if(block ==rhs.block) { if(block&1) return R>rhs.R; else return R<rhs.R; } return block <rhs.block; } }queries[maxn]; int main() { len=sqrt(maxn);///块长度 init(); scanf("%d",&T); for(int i=1; i<=T; i++) { ll l,r; scanf("%lld %lld",&l,&r); queries[i]=Query(l,r,i); } sort(queries+1,queries+T+1); int l=1 ,r=1; ll val=2; for(int i=1; i<=T; i++) { while(l<queries[i].L) { val=(2ll*val%mod+mod-cal(l,r))%mod; l++; } while(l>queries[i].L) { --l; val=(val+cal(l,r))%mod *f[2]%mod; } while(r<queries[i].R) { val=(val+cal(l,++r))%mod; } while(r>queries[i].R) { val=(val-cal(l,r--))%mod; val+=mod; val%=mod; } ans[queries[i].ID]=val; } for(int i=1; i<=T; i++) printf("%lld\n",ans[i]); return 0; }