zoukankan      html  css  js  c++  java
  • 函数 贪心

    【题目描述】

    这里写图片描述 
    【输入格式】 
      三个整数。 
      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
  • 相关阅读:
    51nod 1125 交换机器的最小代价
    货物运输 51Nod
    hihoCode 1075 : 开锁魔法III
    糖果
    区间 GCD
    poj2186--tarjan+缩点(有向图的强连通分量中点的个数)
    Hdu 4738【tanjan求无向图的桥】割边判定定理 dfn[x] < low[y]
    回文树介绍
    回文树总结
    140. 后缀数组(hash + 二分 / 后缀数组)
  • 原文地址:https://www.cnblogs.com/gshdyjz/p/7672644.html
Copyright © 2011-2022 走看看