E. Resistors in Parallel(2018-2019 ACM-ICPC, Asia Jiaozuo Regional Contest)

 http://codeforces.com/gym/102028/problem/E

题意:给n个集合si,si为i的因子集合,这些因子必须不能被平方数整除;s12={1,2,3,6},在这些集合中取一个使得因子倒数和的倒数最小,最简分数表示;(n<=10^100)

思路:大数,取n以内的素因子达到最优,贡献是i/(i+1);

2、100内:1,2,3,5;就是1,2,3,5,2*3,2*5,3*5,2*3*5因子倒数和的倒数;

组合:dp求法很巧;

package javaacm;

import java.util.*;
import java.io.*;
import java.math.*;

public class Main {
	
	static int mod=(int)1e9+7;
	static int maxn=(int)1e5+9;
	
	static boolean [] vis = new boolean [maxn];
	static int [] pre = new int [maxn];
	static int cnt=1;
	
	static BigInteger [] dp =new BigInteger[10009];
	
	public static void P()
	{
		for(int i=2;i<=10000;i++)
		{
			if(!vis[i])
			{
				pre[cnt++]=i;
				for(int j=i+i;j<=10000;j+=i) vis[j]=true;
			}
		}
	}
	
	public static void main(String[] args)
	{
		Scanner cin = new Scanner(new BufferedInputStream(System.in));

		P();
		
		//System.out.println("aaaa");
		
		int cas=cin.nextInt();
		while(cas-->0)
		{
			BigInteger n=cin.nextBigInteger();
			int k=0;
			dp[0]=BigInteger.ONE;
			
			BigInteger sum=BigInteger.ONE;
			
			for(int i=1;;i++)
			{
				if((sum.multiply(BigInteger.valueOf(pre[i]))).compareTo(n)>0) break;
				k=i;
				sum=sum.multiply(BigInteger.valueOf(pre[i]));
				//System.out.println(pre[i]);
			}
			//System.out.println(k);
			for(int i=1;i<=k;i++)
			{
				dp[i]=dp[i-1].add(dp[i-1].multiply(BigInteger.valueOf(pre[i])));
				//System.out.println(dp[i]);
			}
			//System.out.println("aaaa");
			BigInteger g=sum.gcd(dp[k]);
			System.out.println(sum.divide(g)+"/"+dp[k].divide(g));
		}
		
	}
}

 

import math

maxn = 2000

def gcd(x,y):
    if y: return gcd(y,x%y)
    return x

def P():
    isp=[True]*(maxn+10)
    pri=[]
    for i in range(2,maxn):
        if isp[i]:
            pri.append(i)
            for j in range(i*i,maxn,i):
                isp[j]=False
    return pri

t=int(input())
prime = P()
while t:
    n=int(input())
    down=1
    up=1
    sum=1
    for i in prime:
        sum*=i
        if sum>n:break
        up*=i
        down*=i+1
    g=gcd(up,down)
    up//=g
    down//=g
    print(str(up)+'/'+str(down))
    t-=1



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值