2018 焦作 现场赛(打表+数论积性函数)

题意:

定义n种电阻,阻值r[i]= { inf | i%d2==0 && d>1 ,   i | else} 。

然后定义n种电阻集合,S[i]={ j | i%j==0} , 现在询问给定n找出一个集合Si,使得将Si内的电阻

并联之后电阻值最小,输出最简分数格式。

思路:

        确定题意弄了半天,不是依次选择N个电阻,而是有N种选择集合,每种选择中固定有

若干电阻。想不出什么规律打了个表(直接分数转成小数打表打错了,但是只注意到前面

打对的几项,巧合了,,,)。发现 N==x 时 的答案是符合一定规律的,N<=1时取n=1,

1<N<=2时取i=2得最优解,2<N<=6时取 i==6,N<6<=30时 取 i==30,,,呈质数倍数

关系增长。(打分数表的直接把分子分母的规律给打出来了,但我们没打出来,所以打表的

技巧有待加强)。

在只有上述结论的情况下,大佬秀基本操作的时候到了。。。

1、现在已知N,我们要找的是规律序列中第一个大于等于N的数?

      暴力考虑质数相乘 递推过去 即可,N最大10^100,几百个质数相乘就够了,

打个素数表递推,

时间上没问题,精度上可以用Java处理。

2、现在已知 我们从N种方案中选择了 第 i 种方案,怎么计算该方案 i 的并联阻值?

     因为所有参与并联电路的阻值都肯定不包含完全平方数,所以不考虑电阻无穷情况,

(其实包含也不影响,,,),同时,这些电阻值均为 i 的因子,所以对电阻并联公式

通分最后分子等于 i ,分母为 i 的因子和。分子好说,分母的话时间上存在问题。

这里用积性函数优化,设S(N)表示N的因子和,显然N=x*y*...*z。x,y为累乘的质数

们,互质显然的,所以分母变为(x+1)*(y+1)*...*(z+1)。时间解决了,空间大数

即可。

代码实现:

import java.math.BigInteger;
import java.util.Scanner;

public class Main{
	static int t, tot;
	static BigInteger n;
	static int vis[] = new int[1000100];
	static int pri[] = new int[1000100];
	static Scanner cin = new Scanner(System.in);
	
	static void init(int maxsn){
		vis[1]=vis[0]=1;
		for(int i=2;i<=maxsn;i++){
			if(vis[i]==1)continue;
			pri[++tot]=i;
			for(int j=i;j*i<=maxsn;j++)
				vis[i*j]=1;
		}
	}
	static String sol_gcd(BigInteger x,BigInteger y){
		BigInteger zero = new BigInteger("0");
		return y.equals(zero)?x.toString():sol_gcd(y,x.mod(y)); 
	}
	static void sol(){
		BigInteger fz=new BigInteger("1");
		BigInteger fm=new BigInteger("1");
		BigInteger p=null;
		for(int i=1;i<=tot;i++){
			p = BigInteger.valueOf(pri[i]);//*** ***
			if((fz.multiply(p).compareTo(n))==1)break;		
			fz = fz.multiply(p);
			fm = fm.multiply(p.add(new BigInteger("1")));
		}
		BigInteger d = new BigInteger(sol_gcd(fz,fm));
		fz = fz.divide(d);
		fm = fm.divide(d);
		System.out.println(fz+"/"+fm);
	}
	
	public static void main(String args[]){
		t = cin.nextInt();
		tot = 0;
		init(10000);
		while (t > 0) {
			t--;
			n=new BigInteger(cin.next());
			sol();
		}
		cin.close();
	}
}

THE END;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值