【Java】A乘积—方法:BigInteger—(OJ:牛客-练习赛54)

链接:https://ac.nowcoder.com/acm/contest/1842/A
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

在这里插入图片描述 ,即二进制表示下后i位为1,其余位为0的数。给定一个正整数n,求在这里插入图片描述
输出答案对998244353取模后的结果。T组数据。

输入描述:

第一行一个整数T,表示数据组数。
接下来T行每行一个整数n,含义如题目描述所示。

输出描述:

输出T行,表示每次询问的结果。

示例
输入

2
2
4

输出

3
1250235

备注

T≤100, 1≤n≤64。

解释名词

1、Ai

i=1时,A1 表示000…0001;
i=2时,A1 表示000…0011;
i=3时,A1 表示000…0111;
i=4时,A1 表示000…1111;

2、∏

∏是希腊字母,即π的大写形式,在数学中表示求积运算或直积运算。

3、&

在电脑语言中,表示按位进行“与”运算。
即参加运算的两个数,按二进制位进行“与”运算。
规则只有两个数的二进制同时为1,结果才为1,否则为0。
即 0 & 0= 0 ,0 & 1= 0,1 & 0= 0, 1 & 1= 1。

思路:样例解剖

重点在于在这里插入图片描述把样例带入,可以得到以下规律

1、n=2

A1 & A1=> 0000…0001&0000…0001 => 0000…0001(二进制) => 1(十进制)
A1 & A2=> 0000…0001&0000…0011 => 0000…0001(二进制) => 1(十进制)
A2 & A2=> 0000…0011&0000…0001 => 0000…0001(二进制) => 1(十进制)
A2 & A2=> 0000…0011&0000…0011 => 0000…0011(二进制) => 3(十进制)
乘积为:1×1×1×3
取模后:3%998244353=3
输出:3

2、n=4

A1 &(A1 ~ A4 ) => 1×1×1×1
A2 &(A1 ~ A4 ) => 1×3×3×3
A3 &(A1 ~ A4 ) => 1×3×7×7
A4 &(A1 ~ A4 ) => 1×3×7×15

3、研究Ai

i=1时,A1 表示000…0001(二进制) => 1 (十进制)
i=2时,A1 表示000…0011(二进制) => 3 (十进制)
i=3时,A1 表示000…0111(二进制) => 7 (十进制)
i=4时,A1 表示000…1111(二进制) => 15 (十进制)
即后一个是前一个加上2的i次方
Java实现

		int[] e = new int[65];	//1≤n≤64
		e[0] = new int("1");
		for(int i=1; i<e.length; i++) {
			e[i] =e[i-1]+Math.pow(2, i);
			System.out.print(e[i]+" ");
		}

当代码跑起来的时候,会超出范围。
当把int改成long,再次运行成语时,你会发现,最后三个数据一样【笑脸】
没错,这道题逼迫你用Java的BigInteger。

方法:BigInteger

import java.math.BigInteger;

public class Main{
    public static void main(String args[]){
       Scanner sc = new Scanner(System.in);
       BigInteger a = sc.nextBigInteger();
       BigInteger b = sc.nextBigInteger();
       
       //大数基本运算
       System.out.println(a.add(b)); 		//大整数加法
       System.out.println(a.subtract(b)); 	//大整数减法
       System.out.println(a.multiply(b)); 	//大整数乘法
       System.out.println(a.divide(b)); 	//大整数除法
       System.out.println(a.remainder(b)); 	//大整数取模
       
       //大整数的比较
       if( a.compareTo(b) == 0 ) System.out.println("a == b"); 	//大整数a==b
       if( a.compareTo(b) > 0 ) System.out.println("a > b"); 	//大整数a>b
       if( a.compareTo(b) < 0 ) System.out.println("a < b"); 	//大整数a<b
       
       //大整数绝对值
       System.out.println(a.abs()); 	//大整数a的绝对值
       
       //大整数的幂
       int ex=10;
       System.out.println(a.pow(ex)); 	//大整数a的ex次幂
      }
    }
}

运用BigInteger,再次求e;

		BigInteger[] e = new BigInteger[65];
		e[0] = new BigInteger("1");
		for(int i=1; i<e.length; i++) {
			BigInteger e2 = new BigInteger("2");
			BigInteger ep = e2.pow(i);
			e[i] =e[i-1].add(ep);
			System.out.print(e[i]+" ");
		}

Java源代码

package t_牛客_练习赛54;

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

/**
 * https://ac.nowcoder.com/acm/contest/1842/A
 * @Title: A_乘积.java 
 * @author Baisu 
 * @date 2019年11月15日 
 * @version 1.0
 */

public class A_乘积 {

	public static void main(String[] args) {
		Scanner sc  = new Scanner(System.in);
		//输入
		int t = sc.nextInt();
		int[] a = new int [t];
		for(int i=0; i<t; i++) {
			a[i] = sc.nextInt();
		}
		//二进制1转十进制的值
		BigInteger[] e = new BigInteger[65];
		e[0] = new BigInteger("1");
		for(int i=1; i<e.length; i++) {
			BigInteger e2 = new BigInteger("2");
			BigInteger ep = e2.pow(i);
			e[i] =e[i-1].add(ep);
//			System.out.print(e[i]+" ");
		}
		//计算
		BigInteger a0 = new BigInteger("0");
		for(int i=0; i<a.length; i++) {	//第一个数
			if(a[i]==0) {
				System.out.println(0);
			}
			else {				
				BigInteger product = new BigInteger("1");
				for(int j=0; j<a[i]; j++) {	//第一个数循环次数
					int l = 0;
					for(int k=0; k<a[i]; k++) {
						if(l>j) {
							l=j;
						}
						product=product.multiply(e[l]);
						l++;
					}
				}
				BigInteger pt = new BigInteger("998244353");
				System.out.println(product.remainder(pt));
			}
		}
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值