题意:
这个题意是真的很难,问你n个小姐姐选美,应该怎么排比较的次数最少。
每次比较只能两两比较,
然后让你求出中每个f(i)是多少。
题解:
如果i是素数。那么f(i)=i*(i-1)/2;
否则分的组数越多越有利,又因为每个合数都是由若干个质数组成,所以枚举素数即可。
然后dp, dp[x]=dp[y]*(x/y)+dp[x/y];
#include<bits/stdc++.h>
#define ll long long
#define mod 1000000007
using namespace std;
const int maxl=5e6+10;
const int inf=2e9+10;
ll f[maxl];
int prime[maxl],v[maxl];
ll t,l,r,cnt=0;
ll dp[maxl];
void init(){
f[1]=1;
for(int i=2;i<maxl;++i) f[i]=f[i-1]*t%mod;
v[1]=1;
for(int i=2;i<maxl;++i){
if(!v[i]){
prime[++cnt]=i;
}
for(int j=1;j<=cnt&&i*prime[j]<maxl;++j){
v[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
}
void solve(){
dp[1]=0;
for(ll i=2;i<maxl;++i){
if(v[i]){
//dp[i]=i*(i-1)/2;
for(ll j=1;prime[j]<i;++j){
if(i%prime[j]==0){
dp[i]=(dp[prime[j]]*(i/prime[j])+dp[i/prime[j]]);
break;
}
}
}
else dp[i]=(i*(i-1)/2);
dp[i]%=mod;
//if(i>=5e6)printf("%lld %lld %lld\n",i,dp[i],i*(i-1)/2);
}
}
int main(){
scanf("%lld %lld %lld",&t,&l,&r);
init();
solve();
ll ans=0;
for(int i=l;i<=r;++i){
ans=(ans+f[i-l+1]*dp[i]%mod)%mod;
//cout<<ans<<" "<<f[i-l+1]<<" "<<dp[i]<<endl;
}
printf("%lld\n",ans);
return 0;
}