//其实题目中f[n]的值可理解为存在多少个整数对使a*b<=n #include<cstdio> #define N 1007 #define maxn 1000005 using namespace std; int f[maxn]; void Procede(int n)//预处理 { for(int i=1;i<maxn;i++){ for(int j=i;j<maxn;j+=i){ f[j]++; } } //此时f[n]理解为表示n的约数的个数,亦可以理解为表示存在多少对整数对(a,b)恰好满足a*b=n f[1]=1,f[2]=2,f[3]=2,f[8]=4,f[10]=3 for(int j=1;j<maxn;j++){ f[j]=(f[j-1]+f[j])%N; }//f[n]此时表示存在多少对整数对(a,b)满足a*b<=n,即求了一次前缀和,f[1]=1,f[2]=3,f[3]=5 for(int j=1;j<maxn;j++){ f[j]=(f[j-1]+f[j])%N; } }//此时f[n]表示题目中的sum(1,n),即又求了一次前缀和,f[1]=1,f[2]4,f[3]=9 int main() { int a,b; Procede(maxn); while(scanf("%d%d",&a,&b)!=EOF) { int ans=(f[b]-f[a-1]+N)%N; printf("%d\n",ans); } }
这是别人的诗,下面是我的辣鸡代码
#include<cstdio> #include<iostream> using namespace std; const int N=1e6+7; const int mod=1007; int p[N]; int dp[N]; int sum[N]; int main () { for (int i=2;i<=N;i++) { if (!p[i]) p[++p[0]]=i; for (int j=1;j<=p[0]&&i*p[j]<=N;j++) { p[i*p[j]]=1; if (i%p[j]==0) break; } } /* 筛选出素数*/ dp[1]=1; sum[1]=1; int x; for (int u=2;u<=1000000;u++) { x=u; int i=1; int ans=1; while (p[i]*p[i]<=x) { if (x%p[i]==0) { int k=0; while (x%p[i]==0) {k++;x=x/p[i];} ans=ans*(k+1); } i++; } if (x!=1) ans=2*ans; dp[u]=(dp[u-1]+ans)%mod;/* 30 与 29增加多少呢,因为30可以分解为2*3*5三个质因数所以增加3个*/ sum[u]=(sum[u-1]+dp[u])%mod; } int a,b; while (~scanf ("%d %d",&a,&b)) { printf ("%d\n",(sum[b]-sum[a-1]+mod)%mod); } return 0; }
数学真是有意思。。。脑子不够用。。。。。。
抓住青春的尾巴。。。