![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<string.h> 3 #include<stdio.h> 4 #define INF 3000000000 5 #define LL long long 6 using namespace std; 7 8 int main(){ 9 LL n,A,B,l,mod,num,a; 10 LL max1,min,M; 11 while(~scanf("%I64d%I64d%I64d%I64d%I64d",&n,&l,&A,&B,&mod)){ 12 max1=-1,num=0;min=INF;M=l/2; 13 for(LL i=1;i<=n;i++){ 14 if (i==1) a=(A+B)%mod;else a=(a+A)%mod; 15 if (a<=M){ 16 if (a>max1) max1=a; 17 num++; 18 } 19 else{ 20 if (a<min) min=a; 21 } 22 } 23 if (max1+min<=l) num++; 24 printf("%I64d ",num); 25 } 26 return 0; 27 28 }
HDU4372
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /*HDU 4372 组合数学 2 第一类stirling数+排列 3 题意:有n栋高楼,高度属于[1,n]区间,且各不相同,排成一排后, 4 从左边看,有L个,右边看,看到R个(高楼会把矮楼挡住), 5 问,在满足这个条件时,可能有多少的不同排列方式? 6 */ 7 /*我们能知道最高的楼一定能看见,这样左边能看见L-1个,右边能看到R-1个, 8 因为数字各不相同,这样,等于把n-1个不同的数字分成L-1+R-1组,每组中的最高的放在最左边(右边),剩下几个被挡住的,有(k-1)!种排列方式。 9 第一类stirling数的定义: 10 把n个元素集合分作k个环排列的方法 11 我们把这个定义转化一下: 12 环排列:每两个元素的相对位置是一定的,但是环是能够旋转的,对于一个i环,环排列数是i!/i,正好符合这道题目的 13 分好k组后,左边放置L-1组,最大的要从小到大排列 14 所以,最终答案是 S[N-1][L-1+R-1]*C[L-1][L-1+R-1] 15 */ 16 #include <iostream> 17 #include <string.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 #define maxn 2000+5 21 #define mod 1000000007 22 #define LL long long 23 using namespace std; 24 LL C[maxn][maxn]; 25 LL S[maxn][maxn]; 26 27 void init(){ 28 // memset(S,0,sizeof(S)); 29 for(LL i=0;i<maxn;i++) {S[i][0]=0;S[i][i]=1;} 30 for(LL i=1;i<maxn;i++){ 31 for(LL j=1;j<=i;j++){ 32 S[i][j]=(S[i-1][j-1]+(i-1)*S[i-1][j])%mod; 33 } 34 } 35 memset(C,0,sizeof(C)); 36 C[0][0]=1; 37 for(LL i=1;i<maxn;i++){ 38 C[i][0]=1;C[i][i]=1; 39 for(LL j=1;j<maxn;j++) 40 C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod; 41 } 42 } 43 //最终答案是 S[N-1][L-1+R-1]*C[L-1][L-1+R-1] 44 LL t,N,L,R; 45 int main(){ 46 init(); 47 cin>>t; 48 while(t--){ 49 cin>>N>>L>>R; 50 LL ans=(S[N-1][L-1+R-1]*C[L-1+R-1][L-1])%mod; 51 cout<<ans<<endl; 52 } 53 return 0; 54 }