結果

問題 No.1266 7 Colors
ユーザー ks2mks2m
提出日時 2020-10-23 23:14:27
言語 Java21
(openjdk 21)
結果
AC  
実行時間 1,170 ms / 3,000 ms
コード長 4,408 bytes
コンパイル時間 2,807 ms
コンパイル使用メモリ 78,336 KB
実行使用メモリ 91,088 KB
最終ジャッジ日時 2023-09-28 18:25:22
合計ジャッジ時間 23,208 ms
ジャッジサーバーID
(参考情報)
judge12 / judge11
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 47 ms
49,504 KB
testcase_01 AC 47 ms
49,448 KB
testcase_02 AC 47 ms
49,488 KB
testcase_03 AC 890 ms
72,212 KB
testcase_04 AC 1,002 ms
79,408 KB
testcase_05 AC 904 ms
72,040 KB
testcase_06 AC 1,028 ms
83,108 KB
testcase_07 AC 1,004 ms
86,620 KB
testcase_08 AC 1,006 ms
80,332 KB
testcase_09 AC 948 ms
76,020 KB
testcase_10 AC 1,055 ms
74,944 KB
testcase_11 AC 972 ms
73,436 KB
testcase_12 AC 928 ms
68,668 KB
testcase_13 AC 964 ms
72,344 KB
testcase_14 AC 880 ms
70,940 KB
testcase_15 AC 1,170 ms
87,692 KB
testcase_16 AC 939 ms
68,708 KB
testcase_17 AC 1,014 ms
85,324 KB
testcase_18 AC 1,101 ms
89,724 KB
testcase_19 AC 852 ms
91,088 KB
testcase_20 AC 981 ms
91,000 KB
testcase_21 AC 581 ms
65,844 KB
権限があれば一括ダウンロードができます

ソースコード

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(7 * i + j, 7 * 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(7 * u + j, 7 * 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 + 5) % 7;
				if (s[x][a] == '1' && s[x][y1] == '1') {
					uf.merge(7 * x + a, 7 * x + y1);
				}
				a = y % 7;
				if (s[x][a] == '1' && s[x][y1] == '1') {
					uf.merge(7 * x + a, 7 * x + y1);
				}
				for (int v : list.get(x)) {
					if (s[x][y1] == '1' && s[v][y1] == '1') {
						uf.merge(7 * x + y1, 7 * v + y1);
					}
				}
			} else {
				pw.println(uf.size(7 * 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