9.25
bzoj 4403 : 公式推导+lucas定理
对于符合条件的序列把它们都加上下标,那么一个长度为len的序列就是在[L+1,R+len]中选出len个数,即求C(R-L+len,R-L)
#include<cstdio>
#define LL long long
#define P 1000003
using namespace std;
int n,m,l,r;
LL fac[P],inv[P];
void init()
{
int i;
for(fac[0]=1,i=1;i<P;++i)
fac[i]=fac[i-1]*i%P;
for(inv[1]=1,i=2;i<P;++i)
inv[i]=(P-P/i)*inv[P%i]%P;
for(inv[0]=1,i=1;i<P;++i)
(inv[i]*=inv[i-1])%=P;
}
LL lucas(int n,int m)
{
if(n<m) return 0;
if(n<P&&m<P) return fac[n]*inv[m]%P*inv[n-m]%P;
return lucas(n/P,m/P)*lucas(n%P,m%P)%P;
}
int main()
{
int test;
init();
scanf("%d",&test);
while(test--)
{
int n,L,R;
scanf("%d %d %d",&n,&L,&R);
printf("%lld\n",(lucas(n+R-L+1,R-L+1)+P-1ll)%P);
}
return 0;
}
学了一下lucas的姿势看了好多推导感觉好虚啊...
------------------------------------------------------------------------------------------------------
9.28
51nod 1055 最长等差数列
f[i][j]表示含有a[i]和a[j]的等差数列最长长度
如果a[i]+a[k]=a[j]*2(i<j<k) f[j][k]=f[i][j]+1
向两边推一下
#include<cstdio>
#include<algorithm>
#define N 10005
using namespace std;
int n;
int a[N];
short int f[N][N];
int main() {
scanf("%d",&n);
for(int i=1; i<=n; ++i) scanf("%d",&a[i]);
sort(a+1,a+n+1);
int i,j,k;
short int ans=0;
for(i=1; i<=n; ++i)
for(j=i+1;j<=n;++j) f[i][j]=2;
for(j=2; j<n; ++j) {
i=j-1,k=j+1;
while(i>0&&k<n+1) {
if(a[i]+a[k]==a[j]*2) ans=max(ans,f[j][k]=f[i][j]+1),--i,++k;
else if(a[i]>a[j]*2-a[k]) --i;
else if(a[k]<a[j]*2-a[i]) ++k;
}
}
printf("%d",ans);
}
51nod 1120 机器人走方格 V3
卡特兰数
ans=C(2*n,n)-C(2*n,n-1)
模数不大,直接上lucas
#include<cstdio>
#define P 10007
using namespace std;
int n;
int fac[P],inv[P];
void init()
{
int i;
for(fac[0]=1,i=1;i<P;++i)
fac[i]=fac[i-1]*i%P;
for(inv[1]=1,i=2;i<P;++i)
inv[i]=(P-P/i)*inv[P%i]%P;
for(inv[0]=1,i=1;i<P;++i)
(inv[i]*=inv[i-1])%=P;
}
int lucas(int n,int m)
{
if(n<m) return 0;
if(n<P&&m<P) return fac[n]*inv[m]%P*inv[n-m]%P;
return lucas(n/P,m/P)*lucas(n%P,m%P)%P;
}
int main()
{
init();
scanf("%d",&n);--n;
printf("%d\n",(lucas(2*n,n)-lucas(2*n,n-1)+P)%P*2%P);
return 0;
}
------------------------------------------------------------------------------------------------------
10.12
51nod 1462 开坑,有空来做
------------------------------------------------------------------------------------------------------
12.25
题意
求1~n的数的约数总个数
解题报告
#include<cstdio> using namespace std; int n,ans; int main(){ scanf("%d",&n); for(int i=1;i<=n;++i) ans+=n/i; printf("%d\n",ans); }