UESTC - 1429 Easy Calculation

 

先给出题目:
                                                                             
Easy Calculation

 

Time Limit: 1000 ms  Memory Limit: 65536 kB
Solved: 27  Tried: 519

 

Description
KO is a Taobao engineer at infrastructure team. He likes thinking, especially about math and algorithm problem. One day a math puzzle comes to his mind.

Let’s define an equation as follow:

f[1][j] = j, j >= 1;
f[i][1] = 1, i >= 1;
f[i][j] = f[i][j-1] * f[i-1][j],  i > 1 and j > 1;

Given two integers n, m, how to calculate the value of f[n][m] mod 10 9?
 

 

Input

The first line of the input is an integer T (T <= 1000), which stands for the number of test cases you need to solve.

Every test case are two integers n, m (1 <= n, m <= 109).

 

 

Output
For every test case, you should output "Case #k: " first, where k indicates the case number and starts at 1. Then the answer f[n][m] mod 10 9. See sample for more details.
 

 

Sample Input
4
1 2
2 2
2 3
3 3
 

 

Sample Output
Case #1: 2
Case #2: 2
Case #3: 6
Case #4: 12
 

 

Source
The 9th UESTC Programming Contest Preliminary
好恶心,竟然注册不了。好吧,于是这个代码就是没交过的了,不过我99%保证这是对的= =(我打过表了)
这题目蛮变态的,这么大的数组,滚动数组也是开不下的。 于是乎就先把一部分的数字打出来看看咯,看看有什么规律。
可以发现10行5列以后,全都是零。前10列(除第一列)就直接用数组存吧。接下来只用找出3列、4列、5列的规律就好了。
为了抓紧时间睡觉,各列的公式以后再打上来吧。  这题最恶心的地方就是5列的时候没法用64位整形表示(应该说我不知道怎么改用它表示,其实我看交的人里面10多个都是用的C++,不过当然考虑他们用了高精度类的情况),非得逼我用java = =。

 

import java.math.*; import java.util.*; public class EasyCalculation { static long MAXN = 1000000000; static long[][] f = { {0}, {0}, {0, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 227020800, 178291200, 674368000, 789888000, 428096000 ,705728000, 408832000, 176640000, 709440000, 607680000, 976640000, 439360000, 984000000, 584000000, 768000000, 504000000, 616000000, 480000000, 880000000 , 160000000 , 280000000 ,520000000 , 200000000 , 200000000 ,400000000 , 200000000 , 800000000}, {0, 1, 2, 12, 288, 34560, 24883200, 411328000, 744960000, 84800000, 240000000}, {0, 1, 2, 24, 6912, 238878720, 965504000, 312000000}, {0, 1, 2, 48, 331776, 226206720, 986880000}, {0, 1, 2, 96, 31850496, 230533120, 465600000}, {0, 1, 2, 192, 115295232, 554083840, 904000000}, {0, 1, 2, 384, 273369088, 16337920, 680000000}, {0, 1, 2, 768, 947459584, 886625280, 400000000} }; static long pow(long a, BigInteger p) { long ans = 1; BigInteger two = BigInteger.valueOf(2); while(p.compareTo(BigInteger.ZERO) == 1) { if(p.mod(two).compareTo(BigInteger.ONE) == 0) ans = ans * a % MAXN; a = a * a % MAXN; p = p.divide(two); } return ans; } static long pow(long a, long p) { long ans = 1; while(p > 0) { if(p%2 == 1) ans = ans * a % MAXN; a = a * a % MAXN; p/=2; } return ans; } public static void main(String[] args) { int T, cas = 1; long t; int n, m; Scanner scan = new Scanner(System.in); T = scan.nextInt(); while(T-- != 0) { System.out.println("Case #"+ cas++ +":"); n = scan.nextInt(); m = scan.nextInt(); switch(n) { case 1: System.out.println(m); break; case 2: if(m < 40) { System.out.println(f[n][m]); } else { System.out.println("0"); } break; case 3: if(m < 11) { System.out.println(f[n][m]); } else { System.out.println("0"); } break; case 4: if(m < 8) { System.out.println(f[n][m]); } else { System.out.println("0"); } break; case 5: case 6: case 7: case 8: case 9: if(m < 7) { System.out.println(f[n][m]); } else { System.out.println("0"); } break; default: if(m == 1 || m == 2) { System.out.println(m); } else if(m == 3){ t = 3*pow(2, (long)n-1)%MAXN; System.out.println(t); } else if(m == 4) { t = 4*pow(3, (long)n-1)*pow(2, (long)n*(n-1)/2)%MAXN; System.out.println(t); } else if(m == 5) { BigInteger a = BigInteger.valueOf(n-1); BigInteger b = BigInteger.valueOf(n); BigInteger c = BigInteger.valueOf(n+1); a = a.multiply(b).multiply(c).divide(BigInteger.valueOf(6)); //(n^3+3n^2+2n)/6 = n(n+1)(n+2)/6 t = 5*pow(4, (long)n-1)%MAXN*pow(3, (long)n*(n-1)/2)%MAXN*pow(2, a)%MAXN; System.out.println(t); } else { System.out.println("0"); } break; } } } } 

 

最后贴上我打出来的表吧。。。发现太大了,算了。

 

你可能感兴趣的:(Math,Algorithm,Integer,input,import,output)