【數論】codeforces 822D My pretty girl Noora

CN_swords發表於2017-07-29

Link:http://codeforces.com/problemset/problem/822/D

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
/*
codeforces 825D
題意:N個人的比賽,將N個人平均分成N/x組,每組恰好x人。對於每組對f[N]的貢獻為 x⋅(x−1)/2。
同時產生N/x人晉級,其後續操作對f[N]的貢獻為 f[N/x]。直到僅剩一人為止。
給定t,l,r。求區間 [l, r] 的每個f[i],按公式t^0⋅f(l)+t^1⋅f(l+1)+⋯+t^(r−l)⋅f(r)求最小的解。
題解: 若N可以分成x人一組,f[N]=N/x*f[x]+f[N/x],對於N要分成一個人,過程中都是
要經過他的質因子的,無非順序問題,那麼當然先取最小質因子是最優的。
那麼我們需要預處理所有數的最小質因子,利用素數篩即可。
注意:別讓第一次求的最小質因子被後面的數覆蓋了。 
*/
const int Maxn = 5*1e6+6;
const LL mod = 1e9+7;

int Minp[Maxn];
LL f[Maxn];
int main(){
    int t,l,r;
    scanf("%d%d%d",&t,&l,&r);
    LL ans = 0;
    LL pow = 1;
    for(int i = 2; i <= r; i++){
        if(Minp[i] == 0){
            f[i] = ((LL)i*LL(i-1)/2LL)%mod;
            for(int j = i+i; j <= r; j+=i){
                if(Minp[j] == 0)
                    Minp[j] = i;
            }
        }
        else{
            f[i] = ((LL)i/(LL)Minp[i]*f[Minp[i]]+f[i/Minp[i]])%mod;
        }
        if(i >= l){
            ans = (ans+pow*f[i]%mod)%mod;
            pow = pow*(LL)t%mod;
        }
    }
    printf("%I64d\n",ans);
    return 0;
}


相關文章