• 函数 贪心


    【题目描述】

    这里写图片描述 
    【输入格式】 
      三个整数。 
      1≤t<10^9+7,2≤l≤r≤5*10^6 
    【输出格式】 
      一个整数。 
    【输入样例】 
    2 2 4 
    【输出样例】 
    19


     

    第一眼看到这道题,相信都可以想到F函数是要预处理出来的,但是问题就来了:

    怎么得到F函数正确的值呢?

    于是我们需要证明:

    对于n个人,分解成质因数,按质数个人分为一组(从小到大)结果最大。

    证明:

    设a,b是n的质因数,a<b

    于是我们可以得到:

    n=a*b*x;

    于是我们又可以得到:

    F(n)=(F(a)*b+F(b))*x;

    所以当a,b为素数时:

    F(n)=b*x*(a²a+b1)/2;

    通式为:

    F(n)=ab*(ab-1) *x/2;

    因为a,b是素数,所以一定都大于等于2

    所以b*x*(a²a+b1)/2一定大于等于ab*(ab-1) *x/2;

    得证。

    于是有了下面的代码(代码不是我打的,但是注释是我打的):

    #include<cstdio>
    #include<algorithm>
    
    using namespace std;
    
    typedef long long ll;
    
    const ll mods=1e9+7;
    const int N=7000000;
    int pr[N],lp,n,L,R,t;//pr记录素数,lp是第几个素数 
    bool inp[N];//inp记录是不是素数 
    ll F[N],ans,tl;
    
    void getpr()
    {
        inp[1]=1;
        for(int i=2;i<=n;i++)
        {
            if(!inp[i]) 
    			{ 
    				pr[++lp]=i;//记录素数 
    		 		F[i]=(((ll)i*(i-1))>>1)%mods;//F没法分解  
    			}
            for(int j=1;(ll)i*pr[j]<=n && j<=lp;j++)//筛法 
            {
                F[pr[j]*i]=(F[pr[j]]*i%mods+F[i])%mods;//下一个素数相乘的结果为循环到的素数结果乘以组数加上 当前素数结果 
                inp[pr[j]*i]=1;//标记非素数  
            }
        }
    }
    
    int main()
    {
        scanf("%d%d%d",&t,&L,&R);
        n=R; getpr(); tl=1; ans=0;
        for(int i=L;i<=R;i++)
        {
            ll k=F[i];
            ans=(ans+tl*k%mods)%mods;
            tl=tl*t%mods;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    

      

    PEACE
  • 相关阅读:
    java+opencv实现图像灰度化
    java实现高斯平滑
    hdu 3415 单调队列
    POJ 3368 Frequent values 线段树区间合并
    UVA 11795 Mega Man's Mission 状态DP
    UVA 11552 Fewest Flops DP
    UVA 10534 Wavio Sequence DP LIS
    UVA 1424 uvalive 4256 Salesmen 简单DP
    UVA 1099 uvalive 4794 Sharing Chocolate 状态DP
    UVA 1169uvalive 3983 Robotruck 单调队列优化DP
  • 原文地址:https://www.cnblogs.com/gshdyjz/p/7672644.html
Copyright © 2020-2023  润新知