結果

問題 No.1266 7 Colors
ユーザー ks2mks2m
提出日時 2020-10-23 23:07:56
言語 Java21
(openjdk 21)
結果
RE  
実行時間 -
コード長 4,408 bytes
コンパイル時間 4,682 ms
コンパイル使用メモリ 87,856 KB
実行使用メモリ 62,332 KB
最終ジャッジ日時 2024-07-21 12:26:37
合計ジャッジ時間 8,237 ms
ジャッジサーバーID
(参考情報)
judge1 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 54 ms
36,744 KB
testcase_01 AC 54 ms
36,744 KB
testcase_02 AC 57 ms
37,228 KB
testcase_03 RE -
testcase_04 RE -
testcase_05 RE -
testcase_06 RE -
testcase_07 RE -
testcase_08 RE -
testcase_09 RE -
testcase_10 RE -
testcase_11 RE -
testcase_12 RE -
testcase_13 RE -
testcase_14 RE -
testcase_15 RE -
testcase_16 RE -
testcase_17 RE -
testcase_18 RE -
testcase_19 RE -
testcase_20 RE -
testcase_21 RE -
権限があれば一括ダウンロードができます

ソースコード

diff #

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] sa = br.readLine().split(" ");
		int n = Integer.parseInt(sa[0]);
		int m = Integer.parseInt(sa[1]);
		int q = Integer.parseInt(sa[2]);

		DSU uf = new DSU(n * 7);
		char[][] s = new char[n][7];
		for (int i = 0; i < n; i++) {
			s[i] = br.readLine().toCharArray();
			for (int j = 0; j < 7; j++) {
				if (s[i][j] == '1' && s[i][(j + 1) % 7] == '1') {
					uf.merge(n * i + j, n * i + ((j + 1) % 7));
				}
			}
		}

		List<List<Integer>> list = new ArrayList<>();
		for (int i = 0; i < n; i++) {
			list.add(new ArrayList<>());
		}
		for (int i = 0; i < m; i++) {
			sa = br.readLine().split(" ");
			int u = Integer.parseInt(sa[0]) - 1;
			int v = Integer.parseInt(sa[1]) - 1;
			list.get(u).add(v);
			list.get(v).add(u);
			for (int j = 0; j < 7; j++) {
				if (s[u][j] == '1' && s[v][j] == '1') {
					uf.merge(n * u + j, n * v + j);
				}
			}
		}

		PrintWriter pw = new PrintWriter(System.out);
		for (int i = 0; i < q; i++) {
			sa = br.readLine().split(" ");
			int t = Integer.parseInt(sa[0]);
			int x = Integer.parseInt(sa[1]) - 1;
			int y = Integer.parseInt(sa[2]);
			if (t == 1) {
				int y1 = y - 1;
				s[x][y1] = '1';
				int a = (y - 2) % 7;
				if (s[x][a] == '1' && s[x][y1] == '1') {
					uf.merge(n * x + a, n * x + y1);
				}
				a = y % 7;
				if (s[x][a] == '1' && s[x][y1] == '1') {
					uf.merge(n * x + a, n * x + y1);
				}
				for (int v : list.get(x)) {
					if (s[x][y1] == '1' && s[v][y1] == '1') {
						uf.merge(n * x + y1, n * v + y1);
					}
				}
			} else {
				pw.println(uf.size(n * x));
			}
		}
		pw.flush();
		br.close();
	}
}

class DSU {
	private int n;
	private int[] parentOrSize;
	private int num;

	/**
	 * n頂点0辺の無向グラフを作る。<br>
	 * O(n)
	 * 
	 * @param n 頂点数
	 */
	public DSU(int n) {
		this.n = n;
		this.parentOrSize = new int[n];
		Arrays.fill(parentOrSize, -1);
		num = n;
	}

	/**
	 * 辺(a, b)を足す。<br>
	 * ならしO(α(n))
	 * 
	 * @param a 頂点番号(0≦a<n)
	 * @param b 頂点番号(0≦b<n)
	 * @return 代表元
	 */
	int merge(int a, int b) {
		assert 0 <= a && a < n : "a=" + a;
		assert 0 <= b && b < n : "b=" + b;

		int x = leader(a);
		int y = leader(b);
		if (x == y) {
			return x;
		}
		if (-parentOrSize[x] < -parentOrSize[y]) {
			int tmp = x;
			x = y;
			y = tmp;
		}
		parentOrSize[x] += parentOrSize[y];
		parentOrSize[y] = x;
		num--;
		return x;
	}

	/**
	 * 頂点a, bが連結かどうか。<br>
	 * ならしO(α(n))
	 * 
	 * @param a 頂点番号(0≦a<n)
	 * @param b 頂点番号(0≦b<n)
	 * @return true:連結 false:非連結
	 */
	boolean same(int a, int b) {
		assert 0 <= a && a < n : "a=" + a;
		assert 0 <= b && b < n : "b=" + b;

		return leader(a) == leader(b);
	}

	/**
	 * 頂点aの属する連結成分の代表元を返す。<br>
	 * ならしO(α(n))
	 * 
	 * @param a 頂点番号(0≦a<n)
	 * @return 代表元
	 */
	int leader(int a) {
		assert 0 <= a && a < n : "a=" + a;

		if (parentOrSize[a] < 0) {
			return a;
		} else {
			return parentOrSize[a] = leader(parentOrSize[a]);
		}
	}

	/**
	 * 頂点aの属する連結成分の要素数を返す。<br>
	 * ならしO(α(n))
	 * 
	 * @param a 頂点番号(0≦a<n)
	 * @return 要素数
	 */
	int size(int a) {
		assert 0 <= a && a < n : "a=" + a;

		return -parentOrSize[leader(a)];
	}

	/**
	 * 連結成分の数を返す。<br>
	 * O(1)
	 * 
	 * @return 連結成分数
	 */
	int num() {
		return num;
	}

	/**
	 * グラフを連結成分に分けた情報を返す。<br>
	 * O(n)
	 * 
	 * @return 「1つの連結成分の頂点番号のリスト」のリスト
	 */
	List<List<Integer>> groups() {
		int[] leaderBuf = new int[n];
		int[] groupSize = new int[n];
		for (int i = 0; i < n; i++) {
			leaderBuf[i] = leader(i);
			groupSize[leaderBuf[i]]++;
		}
		List<List<Integer>> result = new ArrayList<>(n);
		for (int i = 0; i < n; i++) {
			result.add(new ArrayList<>(groupSize[i]));
		}
		for (int i = 0; i < n; i++) {
			result.get(leaderBuf[i]).add(i);
		}
		result.removeIf(List::isEmpty);
		return result;
	}
}
0