Guest User

Untitled

a guest
Nov 20th, 2017
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.22 KB | None | 0 0
  1. import java.math.BigInteger;
  2. import java.util.Scanner;
  3.  
  4. public class Solution2 {
  5.  
  6. private static final int MAX_K = 1002;
  7. public static final int INT_MODULO = 1000000009;
  8. private static BigInteger[][] memo = new BigInteger[MAX_K][MAX_K];
  9. private static MegaRatio[] bernoulli = new MegaRatio[MAX_K];
  10. private static int maxComputedBernoulli = 0;
  11.  
  12. private static int highwayConstruction(long n, int k) {
  13. if (Math.pow(k, 2) > n) {
  14. BigInteger result = BigInteger.ZERO;
  15. for (long i = 2; i < n; i++) {
  16. result = result.add(BigInteger.valueOf((long) Math.pow(i, k)));
  17. }
  18. return result.mod(BigInteger.valueOf(INT_MODULO)).intValue();
  19. }
  20. MegaRatio result = MegaRatio.ZERO;
  21. if (k > maxComputedBernoulli) {
  22. computeBernoulli(k + 1);
  23. maxComputedBernoulli = k + 1;
  24. }
  25. for (int i = 1, j = k + 1; i <= k + 1; i++, j--) {
  26. if (i - 1 > 2 && i - 1 % 2 == 1)
  27. continue;
  28. MegaRatio coef = calcCoef(i, k, bernoulli);
  29. if (!result.denom.equals(coef.denom)) {
  30. result.num = result.num.add(coef.denom.multiply(
  31. coef.num.multiply(BigInteger.valueOf((long) Math.pow(n - 1, j)))));
  32. result.denom = result.denom.multiply(coef.denom);
  33. } else {
  34. result.num = result.num.add(
  35. coef.num.multiply(BigInteger.valueOf((long) Math.pow(n - 1, j))));
  36. }
  37. }
  38. return result.decimalValue()
  39. .subtract(BigInteger.ONE)
  40. .mod(BigInteger.valueOf(INT_MODULO))
  41. .intValue();
  42. }
  43.  
  44. private static MegaRatio calcCoef(int i, int k, MegaRatio[] bernoulli) {
  45. MegaRatio ber_nbre = bernoulli[i - 1];
  46. return new MegaRatio(combination(k + 1, i - 1).multiply(BigInteger.valueOf((long) Math.pow(-1, i - 1)))
  47. .multiply(ber_nbre.num), ber_nbre.denom.multiply(BigInteger.valueOf(k + 1)));
  48. }
  49.  
  50. private static BigInteger combination(int n, int k) {
  51. return comb(BigInteger.valueOf(n), BigInteger.valueOf(k));
  52. }
  53.  
  54.  
  55. private static BigInteger comb(BigInteger n, BigInteger k) {
  56. if (n.intValue() == 0 && k.intValue() > 0) {
  57. return BigInteger.ZERO;
  58. } else if (k.intValue() == 0 && n.intValue() >= 0) {
  59. return BigInteger.ONE;
  60. } else if (memo[n.intValue()][k.intValue()] != null) {
  61. return memo[n.intValue()][k.intValue()];
  62. } else {
  63. memo[n.intValue()][k.intValue()] =
  64. comb(n.subtract(BigInteger.ONE), k.subtract(BigInteger.ONE))
  65. .add(comb(n.subtract(BigInteger.ONE), k));
  66. }
  67. return memo[n.intValue()][k.intValue()];
  68.  
  69. }
  70.  
  71. private static void computeBernoulli(int m) {
  72. long[][] binomial = new long[m + 1][m + 1];
  73. for (int n = 1; n <= m; n++) binomial[0][n] = 0;
  74. for (int n = 0; n <= m; n++) binomial[n][0] = 1;
  75.  
  76. for (int n = 1; n <= m; n++)
  77. for (int k = 1; k <= m; k++)
  78. binomial[n][k] = binomial[n - 1][k - 1] + binomial[n - 1][k];
  79.  
  80. if (maxComputedBernoulli == 0) {
  81. bernoulli[0] = new MegaRatio(BigInteger.valueOf(1), BigInteger.valueOf(1));
  82. bernoulli[1] = new MegaRatio(BigInteger.valueOf(-1), BigInteger.valueOf(2));
  83. for (int k = 2; k < m; k++) {
  84. bernoulli[k] = MegaRatio.ZERO;
  85. calcKthBernoulli(binomial, k);
  86. }
  87. } else {
  88. for (int k = maxComputedBernoulli + 1; k < m; k++) {
  89. bernoulli[k] = MegaRatio.ZERO;
  90. calcKthBernoulli(binomial, k);
  91. }
  92. }
  93.  
  94. }
  95.  
  96. private static void calcKthBernoulli(long[][] binomial, int k) {
  97. if (k % 2 == 0) {
  98. bernoulli[k] = MegaRatio.ZERO;
  99. for (int i = 0; i < k; i++) {
  100. MegaRatio coef = new MegaRatio(BigInteger.valueOf(binomial[k + 1][k + 1 - i]), BigInteger.valueOf(1));
  101. bernoulli[k] = bernoulli[k].subtract(coef.times(bernoulli[i]));
  102. }
  103. bernoulli[k] = bernoulli[k].divide(new MegaRatio(BigInteger.valueOf(k + 1), BigInteger.valueOf(1)));
  104. }
  105. }
  106.  
  107. public static void main(String[] args) {
  108. Scanner in = new Scanner(System.in);
  109. int q = in.nextInt();
  110. for (int a0 = 0; a0 < q; a0++) {
  111. long n = in.nextLong();
  112. int k = in.nextInt();
  113. int result = highwayConstruction(n, k);
  114. System.out.println(result);
  115. }
  116. in.close();
  117. }
  118. }
  119.  
  120. class MegaRatio {
  121. final static MegaRatio ZERO = new MegaRatio(BigInteger.ZERO, BigInteger.ONE);
  122. BigInteger num, denom;
  123.  
  124. MegaRatio(BigInteger num, BigInteger denom) {
  125. this.num = num;
  126. this.denom = denom;
  127. }
  128.  
  129. private static MegaRatio canonical(BigInteger num, BigInteger denom, boolean checkGcd) {
  130. if (denom.signum() == 0) {
  131. throw new IllegalArgumentException("");
  132. }
  133. if (num.signum() == 0) {
  134. return ZERO;
  135. }
  136. if (denom.signum() < 0) {
  137. num = num.negate();
  138. denom = denom.negate();
  139. }
  140. if (checkGcd) {
  141. BigInteger gcd = num.gcd(denom);
  142. if (!gcd.equals(BigInteger.ONE)) {
  143. num = num.divide(gcd);
  144. denom = denom.divide(gcd);
  145. }
  146. }
  147. return new MegaRatio(num, denom);
  148. }
  149.  
  150. public MegaRatio add(MegaRatio o) {
  151. if (o.num.signum() == 0) {
  152. return this;
  153. } else if (num.signum() == 0) {
  154. return o;
  155. } else if (denom.equals(o.denom)) {
  156. return new MegaRatio(num.add(o.num), denom);
  157. } else {
  158. return canonical(num.multiply(o.denom).add(o.num.multiply(denom)), denom.multiply(o.denom), true);
  159. }
  160. }
  161.  
  162. public MegaRatio multiply(MegaRatio o) {
  163. if (num.signum() == 0 || o.num.signum() == 0) {
  164. return ZERO;
  165. } else if (num.equals(o.denom)) {
  166. return canonical(o.num, denom, true);
  167. } else if (o.num.equals(denom)) {
  168. return canonical(num, o.denom, true);
  169. } else if (num.negate().equals(o.denom)) {
  170. return canonical(o.num.negate(), denom, true);
  171. } else if (o.num.negate().equals(denom)) {
  172. return canonical(num.negate(), o.denom, true);
  173. } else {
  174. return canonical(num.multiply(o.num), denom.multiply(o.denom), true);
  175. }
  176. }
  177.  
  178. public boolean isInteger() {
  179. return num.signum() == 0 || denom.equals(BigInteger.ONE);
  180. }
  181.  
  182. public BigInteger decimalValue() {
  183. return num.divide(denom);
  184. }
  185.  
  186. public MegaRatio negate() {
  187. return new MegaRatio(num.negate(), denom);
  188. }
  189.  
  190. public MegaRatio subtract(MegaRatio o) {
  191. return add(o.negate());
  192. }
  193.  
  194. public MegaRatio invert() {
  195. return canonical(denom, num, false);
  196. }
  197.  
  198. public MegaRatio times(MegaRatio b) {
  199. MegaRatio a = this;
  200.  
  201. MegaRatio c = new MegaRatio(a.num, b.denom);
  202. MegaRatio d = new MegaRatio(b.num, a.denom);
  203. return new MegaRatio(c.num.multiply(d.num), c.denom.multiply(d.denom));
  204. }
  205.  
  206. public MegaRatio divide(MegaRatio o) {
  207. return multiply(o.invert());
  208. }
  209. }
Add Comment
Please, Sign In to add comment