結果
問題 | No.510 二次漸化式 |
ユーザー | Grenache |
提出日時 | 2017-05-12 19:27:49 |
言語 | Java21 (openjdk 21) |
結果 |
AC
|
実行時間 | 882 ms / 3,000 ms |
コード長 | 6,709 bytes |
コンパイル時間 | 4,013 ms |
コンパイル使用メモリ | 78,672 KB |
実行使用メモリ | 111,488 KB |
最終ジャッジ日時 | 2024-09-15 10:45:14 |
合計ジャッジ時間 | 27,041 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 52 ms
37,244 KB |
testcase_01 | AC | 53 ms
37,016 KB |
testcase_02 | AC | 371 ms
46,156 KB |
testcase_03 | AC | 380 ms
46,784 KB |
testcase_04 | AC | 387 ms
46,560 KB |
testcase_05 | AC | 382 ms
46,392 KB |
testcase_06 | AC | 541 ms
54,428 KB |
testcase_07 | AC | 518 ms
54,348 KB |
testcase_08 | AC | 532 ms
54,272 KB |
testcase_09 | AC | 542 ms
54,892 KB |
testcase_10 | AC | 244 ms
45,248 KB |
testcase_11 | AC | 250 ms
45,584 KB |
testcase_12 | AC | 244 ms
44,828 KB |
testcase_13 | AC | 247 ms
45,508 KB |
testcase_14 | AC | 243 ms
45,164 KB |
testcase_15 | AC | 250 ms
45,672 KB |
testcase_16 | AC | 625 ms
106,312 KB |
testcase_17 | AC | 621 ms
106,388 KB |
testcase_18 | AC | 631 ms
106,476 KB |
testcase_19 | AC | 630 ms
106,508 KB |
testcase_20 | AC | 619 ms
106,544 KB |
testcase_21 | AC | 628 ms
106,544 KB |
testcase_22 | AC | 646 ms
106,556 KB |
testcase_23 | AC | 872 ms
111,168 KB |
testcase_24 | AC | 870 ms
111,224 KB |
testcase_25 | AC | 851 ms
111,488 KB |
testcase_26 | AC | 878 ms
111,220 KB |
testcase_27 | AC | 882 ms
111,180 KB |
testcase_28 | AC | 868 ms
111,292 KB |
testcase_29 | AC | 859 ms
111,328 KB |
testcase_30 | AC | 879 ms
111,432 KB |
testcase_31 | AC | 744 ms
109,552 KB |
testcase_32 | AC | 741 ms
109,544 KB |
testcase_33 | AC | 761 ms
109,488 KB |
testcase_34 | AC | 702 ms
105,364 KB |
testcase_35 | AC | 650 ms
105,384 KB |
ソースコード
import java.io.*; import java.util.*; public class Main_yukicoder510 { private static Scanner sc; private static Printer pr; private static void solve() { int n = sc.nextInt(); nn = 1; while (nn < n) { nn *= 2; } st = new int[2 * nn - 1][][]; for (int i = 0; i < n; i++) { st[i + nn - 1] = setM(Matrix.getI(4), 0, 0); } for (int i = n; i < nn; i++) { st[i + nn - 1] = Matrix.getI(4); } for (int i = nn - 2; i >= 0; i--) { st[i] = Matrix.mul(st[2 * i + 2], st[2 * i + 1]); } int q = sc.nextInt(); for (int k = 0; k < q; k++) { char[] xya = sc.next().toCharArray(); if (xya[0] == 'x') { int i = sc.nextInt(); int v = sc.nextInt(); update(i, v, st[nn - 1 + i][1][1]); } else if (xya[0] == 'y') { int i = sc.nextInt(); int v = sc.nextInt(); update(i, st[nn - 1 + i][0][2], v); } else { int i = sc.nextInt(); if (i == 0) { pr.println(1); } else { int[] a0 = {1, 1, 1, 1}; int[] ans = Matrix.mul(query(0, i), a0); pr.println(ans[0]); } } } } private static int nn; private static int[][][] st; // a, b:0-indexed // [a, b) private static int[][] query(int a, int b) { return query(a, b, 0, 0, nn); } private static int[][] query(int a, int b, int i, int l, int r) { if (a >= r || b <= l) { return Matrix.getI(4); } if (a <= l && b >= r) { return st[i]; } return Matrix.mul(query(a, b, i * 2 + 2, (l + r) / 2, r), query(a, b, i * 2 + 1, l, (l + r) / 2)); } // i:0-indexed private static void update(int i, int x, int y) { i = nn - 1 + i; setM(st[i], x, y); while (i > 0) { i = (i - 1) / 2; st[i] = Matrix.mul(st[2 * i + 2], st[2 * i + 1]); } } private static final int MOD = 1_000_000_007; private static int[][] setM(int[][] ret, int x, int y) { ret[0][2] = x; ret[1][1] = y; ret[1][3] = 1; ret[2][1] = 2 * y % MOD; ret[2][2] = (int)((long)y * y % MOD); ret[2][3] = 1; return ret; } private static class Matrix { static int[] mul(int[][] a, int[] x) { int m = a.length; int n = a[0].length; if (n != x.length) { throw new IllegalArgumentException(); } int[] y = new int[m]; for (int i = 0; i < m; i++) { long tmp = 0; for (int j = 0; j < n; j++) { tmp += (long)a[i][j] * x[j]; tmp %= MOD; } y[i] = (int)tmp; } return y; } static int[][] mul(int[][] a, int[][] a2) { int m = a.length; int n = a2[0].length; int l = a[0].length; if (l != a2.length) { throw new IllegalArgumentException(); } int[][] y = new int[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { long tmp = 0; for (int k = 0; k < l; k++) { tmp += (long)a[i][k] * a2[k][j]; tmp %= MOD; } y[i][j] = (int)tmp; } } return y; } static int[][] getI(int n) { int[][] mat = new int[n][]; for (int i = 0; i < n; i++) { mat[i] = new int[n]; mat[i][i] = 1; } return mat; } } // --------------------------------------------------- public static void main(String[] args) { sc = new Scanner(System.in); pr = new Printer(System.out); solve(); pr.close(); sc.close(); } @SuppressWarnings("unused") private static class Scanner { BufferedReader br; Scanner (InputStream in) { br = new BufferedReader(new InputStreamReader(in)); } private boolean isPrintable(int ch) { return ch >= '!' && ch <= '~'; } private boolean isCRLF(int ch) { return ch == '\n' || ch == '\r' || ch == -1; } private int nextPrintable() { try { int ch; while (!isPrintable(ch = br.read())) { if (ch == -1) { throw new NoSuchElementException(); } } return ch; } catch (IOException e) { throw new NoSuchElementException(); } } String next() { try { int ch = nextPrintable(); StringBuilder sb = new StringBuilder(); do { sb.appendCodePoint(ch); } while (isPrintable(ch = br.read())); return sb.toString(); } catch (IOException e) { throw new NoSuchElementException(); } } int nextInt() { try { // parseInt from Integer.parseInt() boolean negative = false; int res = 0; int limit = -Integer.MAX_VALUE; int radix = 10; int fc = nextPrintable(); if (fc < '0') { if (fc == '-') { negative = true; limit = Integer.MIN_VALUE; } else if (fc != '+') { throw new NumberFormatException(); } fc = br.read(); } int multmin = limit / radix; int ch = fc; do { int digit = ch - '0'; if (digit < 0 || digit >= radix) { throw new NumberFormatException(); } if (res < multmin) { throw new NumberFormatException(); } res *= radix; if (res < limit + digit) { throw new NumberFormatException(); } res -= digit; } while (isPrintable(ch = br.read())); return negative ? res : -res; } catch (IOException e) { throw new NoSuchElementException(); } } long nextLong() { try { // parseLong from Long.parseLong() boolean negative = false; long res = 0; long limit = -Long.MAX_VALUE; int radix = 10; int fc = nextPrintable(); if (fc < '0') { if (fc == '-') { negative = true; limit = Long.MIN_VALUE; } else if (fc != '+') { throw new NumberFormatException(); } fc = br.read(); } long multmin = limit / radix; int ch = fc; do { int digit = ch - '0'; if (digit < 0 || digit >= radix) { throw new NumberFormatException(); } if (res < multmin) { throw new NumberFormatException(); } res *= radix; if (res < limit + digit) { throw new NumberFormatException(); } res -= digit; } while (isPrintable(ch = br.read())); return negative ? res : -res; } catch (IOException e) { throw new NoSuchElementException(); } } float nextFloat() { return Float.parseFloat(next()); } double nextDouble() { return Double.parseDouble(next()); } String nextLine() { try { int ch; while (isCRLF(ch = br.read())) { if (ch == -1) { throw new NoSuchElementException(); } } StringBuilder sb = new StringBuilder(); do { sb.appendCodePoint(ch); } while (!isCRLF(ch = br.read())); return sb.toString(); } catch (IOException e) { throw new NoSuchElementException(); } } void close() { try { br.close(); } catch (IOException e) { // throw new NoSuchElementException(); } } } private static class Printer extends PrintWriter { Printer(PrintStream out) { super(out); } } }