时间限制: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));
}
}
}
}