这段代码的哪一部分减慢了我的程序
which part of this code is slowing my program
我正在使用以下代码回答竞赛问题:
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
import java.math.BigInteger;
//ans is modulu 998244353
public class ShiftAndAdd {
private static long mod = 998244353;
private static Scanner input = new Scanner(System.in);
public static void main(String[] args)throws IOException {
BigInteger ans=new BigInteger("0");
int n,m;
BigInteger numb_a,numb_b;
n= input.nextInt();
m=input.nextInt();
numb_a=input.nextBigInteger();
numb_b=input.nextBigInteger();
long[] a = new long[n];
long[] b = new long[m];
long[] a1 = new long[n];//will contain indices of cells of "a" containing 1's
long[] b1 = new long[m];
int ka1=0;//will be actual length of a1
int kb1=0;//will be actual length of b1
for(int i=0;i<n;i++) {
a[n-1-i]=numb_a.longValue()%10;
numb_a=numb_a.divide(new BigInteger("10"));
}
for(int i=0;i<m;i++) {
b[m-1-i]=numb_b.longValue()%10;
numb_b=numb_b.divide(new BigInteger("10"));
}
int a1start=(m>=n)?m-n:0;
ka1=a1start;
for(int i=0;i<n;i++)
if(a[i]==1)
a1[ka1++]=i;
int counter=0;
for(int i=0;i<m;i++)
if(b[i]==1)
b1[kb1++]+=++counter;
else b1[kb1++]=counter;
//answer:
for(int i=a1start;i<ka1;i++) {
ans=ans.add(BigInteger.valueOf((fastExp((long)2,(n-1-a1[i]))%mod *b1[(int)(a1[i]+a1start)] %mod)%mod));
}
print(ans.longValue());
}//end main
private static long fastExp(long a,long b) {
if(b>0) {
if(b%2==0)
return fastExp((a%mod*a%mod)%mod,b/2);
else return (a%mod*fastExp(a,b-1)%mod)%mod;
}
return 1;
}//end method fastExp
private static void print(long t) {
System.out.println(t);
}//end method print
}//end class ShiftAndAdd
然而,在线编译器告诉我一些输入超出了时间限制(输入非常非常大的整数到变量 numb_a 和 numb_b)
我的问题是我不知道哪里超过了时间限制,是因为 class BigInteger 的方法很慢而读取整数吗?还是因为方法慢 valueOf 和 add of this class?
我需要知道尝试修复它的原因
如果你不必使用 java.math.BigInteger 最好使用原始 long 代替,使用不可变对象有利于可伸缩性,但因为你不是 运行 多线程不会得到使用它的好处,但会得到 GC 的缺点,如果你使用对象比使用原语更多,GC 将工作得更频繁。
我正在使用以下代码回答竞赛问题:
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
import java.math.BigInteger;
//ans is modulu 998244353
public class ShiftAndAdd {
private static long mod = 998244353;
private static Scanner input = new Scanner(System.in);
public static void main(String[] args)throws IOException {
BigInteger ans=new BigInteger("0");
int n,m;
BigInteger numb_a,numb_b;
n= input.nextInt();
m=input.nextInt();
numb_a=input.nextBigInteger();
numb_b=input.nextBigInteger();
long[] a = new long[n];
long[] b = new long[m];
long[] a1 = new long[n];//will contain indices of cells of "a" containing 1's
long[] b1 = new long[m];
int ka1=0;//will be actual length of a1
int kb1=0;//will be actual length of b1
for(int i=0;i<n;i++) {
a[n-1-i]=numb_a.longValue()%10;
numb_a=numb_a.divide(new BigInteger("10"));
}
for(int i=0;i<m;i++) {
b[m-1-i]=numb_b.longValue()%10;
numb_b=numb_b.divide(new BigInteger("10"));
}
int a1start=(m>=n)?m-n:0;
ka1=a1start;
for(int i=0;i<n;i++)
if(a[i]==1)
a1[ka1++]=i;
int counter=0;
for(int i=0;i<m;i++)
if(b[i]==1)
b1[kb1++]+=++counter;
else b1[kb1++]=counter;
//answer:
for(int i=a1start;i<ka1;i++) {
ans=ans.add(BigInteger.valueOf((fastExp((long)2,(n-1-a1[i]))%mod *b1[(int)(a1[i]+a1start)] %mod)%mod));
}
print(ans.longValue());
}//end main
private static long fastExp(long a,long b) {
if(b>0) {
if(b%2==0)
return fastExp((a%mod*a%mod)%mod,b/2);
else return (a%mod*fastExp(a,b-1)%mod)%mod;
}
return 1;
}//end method fastExp
private static void print(long t) {
System.out.println(t);
}//end method print
}//end class ShiftAndAdd
然而,在线编译器告诉我一些输入超出了时间限制(输入非常非常大的整数到变量 numb_a 和 numb_b) 我的问题是我不知道哪里超过了时间限制,是因为 class BigInteger 的方法很慢而读取整数吗?还是因为方法慢 valueOf 和 add of this class? 我需要知道尝试修复它的原因
如果你不必使用 java.math.BigInteger 最好使用原始 long 代替,使用不可变对象有利于可伸缩性,但因为你不是 运行 多线程不会得到使用它的好处,但会得到 GC 的缺点,如果你使用对象比使用原语更多,GC 将工作得更频繁。