結果

問題 No.387 ハンコ
ユーザー 37zigen37zigen
提出日時 2016-07-02 02:22:00
言語 Java21
(openjdk 21)
結果
TLE  
実行時間 -
コード長 5,698 bytes
コンパイル時間 2,351 ms
コンパイル使用メモリ 80,232 KB
実行使用メモリ 196,652 KB
最終ジャッジ日時 2024-10-12 01:56:56
合計ジャッジ時間 15,032 ms
ジャッジサーバーID
(参考情報)
judge3 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 TLE -
testcase_01 -- -
testcase_02 -- -
testcase_03 -- -
testcase_04 -- -
testcase_05 -- -
testcase_06 -- -
testcase_07 -- -
testcase_08 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

package yukicoder;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Iterator;

public class Main {
	public static void main(String[] args) {
		new Main().solver();
	}

	void solver() {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		int[] a = new int[N];
		int[] b = new int[N];
		for (int i = 0; i < N; i++) {
			a[i] = sc.nextInt() - 1;
		}
		for (int i = 0; i < N; i++) {
			b[i] = sc.nextInt();
		}
		int[] ret = new int[2 * N];
		int[] d = new int[N];
		int[] c = new int[2 * N];
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (a[j] == i)
					d[j] = 1;
				else
					d[j] = 0;
			}
			c = convolute(d, b);
//			tr(c);
			for (int j = 0; j < 2 * N - 1; j++) {
				if (c[j] > 0) {
					ret[j]++;
				}
			}
		}
		Printer pr = new Printer(System.out);
		for (int i = 0; i < 2 * N - 1; i++) {
			if (ret[i] % 2 == 0) {
				pr.println("EVEN");
			} else {
				pr.println("ODD");
			}
		}
		pr.close();

	}

	void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}

	public static double[][] doFFT(double[] srcRe, double[] srcIm) {
		int n = srcRe.length;
		if (Integer.bitCount(n) != 1)
			return null;
		int[] rev = reverseBitOrder(n);

		double[] dstRe = new double[n];
		double[] dstIm = new double[n];

		for (int i = 0; i < n; i++) {
			dstRe[i] = srcRe[rev[i]];
			dstIm[i] = srcIm[rev[i]];
		}

		for (int s = 1; s <= n; s <<= 1) {
			int nt = s >>> 1;
			int bs = nt;

			double wRe = 1.0;
			double wIm = 0.0;
			double uRe = Math.cos(Math.PI / bs);
			double uIm = -Math.sin(Math.PI / bs);

			for (int t = 0; t < nt; t++) {
				for (int j = t; j < n; j += s) {
					int jp = j + bs;
					double re = dstRe[jp] * wRe - dstIm[jp] * wIm;
					double im = dstRe[jp] * wIm + dstIm[jp] * wRe;
					dstRe[jp] = dstRe[j] - re;
					dstIm[jp] = dstIm[j] - im;
					dstRe[j] += re;
					dstIm[j] += im;
				}
				double nwRe = wRe * uRe - wIm * uIm;
				double nwIm = wRe * uIm + wIm * uRe;
				wRe = nwRe;
				wIm = nwIm;
			}
		}
		return new double[][] { dstRe, dstIm };
	}

	protected static int[] reverseBitOrder(int n) {
		int[] ret = new int[n];
		ret[0] = 0;
		for (int i = 1, h = n >> 1; i < n; i <<= 1, h >>>= 1) {
			for (int j = 0; j < i; j++) {
				ret[j + i] = ret[j] + h;
			}
		}
		return ret;
	}

	public static int[] convolute(int[] a, int[] b) {
		int m = Integer.highestOneBit(a.length | b.length) << 2;
		prepareFFT(m);
		double[][] fa = doFFFT(a, m);
		double[][] fb = doFFFT(b, m);
		double[][] fced = new double[2][m];
		for (int i = 0; i < m; i++) {
			fced[0][i] = (fa[0][i] * fb[0][i] - fa[1][i] * fb[1][i]) / m;
			fced[1][i] = (fa[0][i] * fb[1][i] + fa[1][i] * fb[0][i]) / -m;
		}
		double[][] ced = doFFFT(fced[0], fced[1]);
		int[] ret = new int[m];
		for (int i = 0; i < m; i++) {
			ret[i] = (int) Math.round(ced[0][i]);
		}
		return ret;
	}

	static int[] rev;
	static double[] coss;

	public static void prepareFFT(int n) {
		rev = reverseBitOrder(n);
		coss = new double[n + 1];
		for (int i = 0; i <= n >>> 1; i++) {
			coss[n - i] = coss[i] = Math.cos(Math.PI * i / (n >>> 1));
		}
	}

	public static double[][] doFFFT(int[] srcRe, int n) {
		int m = srcRe.length;
		double[] dstRe = new double[n];
		double[] dstIm = new double[n];

		for (int i = 0; i < n; i++) {
			if (rev[i] < m) {
				dstRe[i] = srcRe[rev[i]];
			}
		}

		for (int s = 1; s <= n; s <<= 1) {
			int nt = s >>> 1;
			int bs = nt;

			for (int t = 0; t < nt; t++) {
				double wRe = coss[t * (n / s)];
				double wIm = coss[(n >>> 2) + t * (n / s)];
				for (int j = t; j < n; j += s) {
					int jp = j + bs;
					double re = dstRe[jp] * wRe - dstIm[jp] * wIm;
					double im = dstRe[jp] * wIm + dstIm[jp] * wRe;
					dstRe[jp] = dstRe[j] - re;
					dstIm[jp] = dstIm[j] - im;
					dstRe[j] += re;
					dstIm[j] += im;
				}
			}
		}
		return new double[][] { dstRe, dstIm };
	}

	public static double[][] doFFFT(double[] srcRe, double[] srcIm) {
		int n = srcRe.length;
		double[] dstRe = new double[n];
		double[] dstIm = new double[n];

		for (int i = 0; i < n; i++) {
			dstRe[i] = srcRe[rev[i]];
			dstIm[i] = srcIm[rev[i]];
		}

		for (int s = 2; s <= n; s <<= 1) {
			int nt = s >>> 1;
			int bs = nt;

			for (int t = 0; t < nt; t++) {
				double wRe = coss[t * (n / s)];
				double wIm = coss[(n >>> 2) + t * (n / s)];
				for (int j = t; j < n; j += s) {
					int jp = j + bs;
					double re = dstRe[jp] * wRe - dstIm[jp] * wIm;
					double im = dstRe[jp] * wIm + dstIm[jp] * wRe;
					dstRe[jp] = dstRe[j] - re;
					dstIm[jp] = dstIm[j] - im;
					dstRe[j] += re;
					dstIm[j] += im;
				}
			}
		}
		return new double[][] { dstRe, dstIm };
	}

	private static class Scanner {
		BufferedReader br;
		Iterator<String> it;

		Scanner(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

		String next() throws RuntimeException {
			try {
				if (it == null || !it.hasNext())
					it = Arrays.asList(br.readLine().split(" ")).iterator();
				return it.next();
			} catch (IOException e) {
				throw new IllegalStateException();
			}
		}

		int nextInt() throws RuntimeException {
			return Integer.parseInt(next());
		}

		long nextLong() throws RuntimeException {
			return Long.parseLong(next());
		}

		double nextDouble() throws RuntimeException {
			return Double.parseDouble(next());
		}

		void close() {
			try {
				br.close();
			} catch (IOException e) {
				throw new IllegalStateException();
			}
		}
	}

	private static class Printer extends PrintWriter {
		Printer(PrintStream out) {
			super(out);
		}
	}

}
0