题意:
给定T组询问,每组有两个数字n和m,求sigma i=0..m c(n,i) 答案对1e9+7取模
T<=1e5
1<=n,m<=1e5
思路:
注意要先变n再变m,否则会因n太小有些组合数会丢失
关键点在于n的转移,m的转移谁都会
预处理数组越界要小心
1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned int uint; 14 typedef unsigned long long ull; 15 typedef pair<int,int> PII; 16 typedef vector<int> VI; 17 #define fi first 18 #define se second 19 #define MP make_pair 20 #define MOD 1000000007 21 #define N 110000 22 23 struct data{int x,y,id;}a[N]; 24 ll ans[N+10],fac[N+10],inv[N+10],inv2; 25 int pos[N+10],m; 26 27 bool cmp(data a,data b) 28 { 29 if(pos[a.x]==pos[b.x]) return a.y<b.y; 30 return a.x<b.x; 31 } 32 33 int read() 34 { 35 int v=0,f=1; 36 char c=getchar(); 37 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 38 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 39 return v*f; 40 } 41 42 ll c(int x,int y) 43 { 44 ll t=fac[x]*inv[y]%MOD*inv[x-y]%MOD; 45 return t; 46 } 47 48 void solve() 49 { 50 ll sum=0; 51 for(int i=0;i<=a[1].y;i++) sum=(sum+c(a[1].x,i))%MOD; 52 int nowx=a[1].x,nowy=a[1].y; 53 ans[a[1].id]=sum; 54 for(int i=2;i<=m;i++) 55 { 56 while(nowx>a[i].x) 57 { 58 sum=(sum+c(nowx-1,nowy))%MOD; 59 sum=sum*inv2%MOD; 60 nowx--; 61 } 62 while(nowx<a[i].x) 63 { 64 sum=(sum*2-c(nowx,nowy)+MOD)%MOD; 65 nowx++; 66 } 67 while(nowy>a[i].y) 68 { 69 sum=(sum-c(nowx,nowy)+MOD)%MOD; 70 nowy--; 71 } 72 while(nowy<a[i].y) 73 { 74 sum=(sum+c(nowx,nowy+1)+MOD)%MOD; 75 nowy++; 76 } 77 ans[a[i].id]=sum; 78 } 79 } 80 81 void init() 82 { 83 fac[0]=1; 84 for(int i=1;i<=N;i++) fac[i]=fac[i-1]*i%MOD; 85 inv[0]=inv[1]=1; 86 for(int i=2;i<=N;i++) inv[i]=inv[MOD%i]*(MOD-MOD/i)%MOD; 87 inv2=inv[2]; 88 for(int i=1;i<=N;i++) inv[i]=inv[i-1]*inv[i]%MOD; 89 int block=int(sqrt(N)); 90 for(int i=1;i<=N;i++) pos[i]=(i-1)/block+1; 91 } 92 93 int main() 94 { 95 //freopen("1.in","r",stdin); 96 //freopen("1.out","w",stdout); 97 scanf("%d",&m); 98 for(int i=1;i<=m;i++) 99 { 100 scanf("%d%d",&a[i].x,&a[i].y); 101 a[i].id=i; 102 } 103 init(); 104 sort(a+1,a+m+1,cmp); 105 solve(); 106 for(int i=1;i<=m;i++) printf("%lld ",ans[i]); 107 return 0; 108 }