• 素数


    前言

    自闭,数学差果然是这样的

    题目

    【问题描述】

    我们定义(v(i))表示小于等于(i)的最大素数,(u(i))表示大于(i)的最小素数,求(sum_{i=2}^nfrac{1}{v(i)u(i)})的值,以最简分数的形式输出。

    【输入描述】

    第一行一个正整数(t),表示测试数据数量
    每组测试数据一行一个正整数(n)

    【输出描述】

    对于每组测试数据输出一个答案。

    【样例】

    Sample Input

    2
    2 3
    

    Sample Output

    1/6
    7/30
    

    【数据范围】

    对于(30\%)的数据,(t <= 10,n <= 10^4)
    对于(100\%)的数据,(t <= 500,n <= 10^9)

    讲解

    我们将(v(i),u(i))相同的一些数提出来康康

    [sum_{i=1}^{u(i)-v(i)}frac{1}{v(i)u(i)}=frac{1}{v(i)}-frac{1}{u(i)} ]

    裂项!

    于是对于(n),我们找出(v(n),u(n))

    [egin{aligned} sum_{i=2}^{n}&=sum_{i=2}^{v(n)-1}+sum_{v(n)}^{n}\ &=frac{1}{2}-frac{1}{v(n)}+frac{n-v(n)+1}{u(n)v(n)}\ &=frac{v(n)u(n)-2u(n)+2(n-v(n)+1)}{2v(n)u(n)} end{aligned}]

    然后化简即可

    什么?你问我怎么找(v(n),u(n))

    难道没人告诉过你质数在(n)以内的分布大概有(frac{n}{ln n})个?

    所以平摊下来我们暴力找只需要(ln n)的时间就可以找到了

    甚至还可以用(O(sqrt n))的时间判断质数,这并不会TLE

    记得开( exttt{long long})

    代码

    bool prime(int x)
    {
    	for(int i = 2;i*i <= x;++ i)
    		if(x % i == 0)
    			return 0;
    	return 1;
    }
    LL gcd(LL x,LL y)
    {
    	if(!y) return x;
    	return gcd(y,x%y);
    }
    
    int main()
    {
    //	freopen("prime_0.in","r",stdin);
    //	freopen("mine.out","w",stdout);
    	for(int T = Read(); T ;-- T)
    	{
    		n = Read();
    		if(n == 2) {printf("1/6
    ");continue;}
    		LL v = n,u = n+1;
    		while(!prime(v)) v--;
    		while(!prime(u)) u++;
    		LL fz = v*u - 2*u + 2*(n-v+1),fm = 2*v*u;
    		LL d = gcd(fz,fm);
    		fz /= d; fm /= d;
    		Put(fz,'/'),Put(fm,'
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    数据库索引(Oracle和Mysql)学习总结
    个人开源Git地址
    关于SQL优化这些你了解吗?
    Java项目排查cpu负载高
    Java Bean与Map之间相互转化的实现
    Maven项目改为spring boot项目的方法
    spring boot从redis取缓存发生java.lang.ClassCastException异常
    MySQL优化之Explain命令解读
    阿里巴巴校招四面经验分享
    HDBS之应用代码优化
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/14053097.html
Copyright © 2020-2023  润新知