Skip to content

Commit 146fdc9

Browse files
authored
Merge pull request #593 from AlgorithmWithGod/0224LJH
2 parents b9e3ee5 + 5650e5b commit 146fdc9

File tree

2 files changed

+270
-0
lines changed

2 files changed

+270
-0
lines changed

0224LJH/202508/2 BOJ XOR.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
```java
2+
import java.io.BufferedReader;
3+
import java.io.IOException;
4+
import java.io.InputStreamReader;
5+
import java.util.StringTokenizer;
6+
7+
8+
public class Main {
9+
10+
static final int UPDATE = 1;
11+
static final int QUERY = 2;
12+
static int size, changeCnt, sumCnt,queryCnt;
13+
static long[] input;
14+
static StringBuilder sb = new StringBuilder();
15+
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
16+
17+
static class SegmentTree{
18+
private long[] lazy; //레이지 프로파게이션
19+
public long[] tree;
20+
private int size; // 원본 배열의 크기
21+
22+
public SegmentTree(long[] arr){
23+
size = arr.length;
24+
this.lazy = new long[size*4];
25+
this.tree = new long[size*4];
26+
build(arr,1,0,size-1);
27+
}
28+
29+
private void build(long[] arr, int node, int startIdx, int endIdx){
30+
if(startIdx == endIdx){
31+
tree[node] = arr[startIdx];
32+
return;
33+
}
34+
35+
int mid = (startIdx + endIdx)/2;
36+
build(arr,node*2,startIdx,mid);
37+
build(arr,node*2+1,mid+1,endIdx);
38+
tree[node] = tree[node*2]^tree[node*2+1];
39+
}
40+
41+
public void updateRange(int startIdx , int endIdx, long k ){
42+
updateRange(1, 0, size-1, startIdx, endIdx, k);
43+
}
44+
45+
private void updateRange(int node,int left,int right, int startIdx , int endIdx, long k){
46+
updateLazy(node, left, right);
47+
48+
if ( left > endIdx || right < startIdx) return; //현 구간과 업데이트 구간이 아예 안겹칩
49+
50+
if (left >= startIdx && right <= endIdx){ // 완전히 포함되는 경우
51+
// XOR의 특성: 구간 길이가 홀수일 때만 실제로 값이 변함
52+
int rangeLength = right - left + 1;
53+
if (rangeLength % 2 == 1) {
54+
tree[node] ^= k;
55+
}
56+
57+
// 리프 노드가 아니라면 lazy 전파
58+
if (left != right) {
59+
lazy[2*node] ^= k;
60+
lazy[2*node+1] ^= k;
61+
}
62+
return;
63+
}
64+
65+
int mid = (left+right)/2;
66+
67+
updateRange(node*2, left, mid, startIdx, endIdx, k);
68+
updateRange(node*2+1, mid+1, right, startIdx, endIdx, k);
69+
70+
updateLazy(node*2, left, mid);
71+
updateLazy(node*2+1, mid+1,right);
72+
tree[node] = tree[node*2]^tree[node*2+1];
73+
}
74+
75+
private void updateLazy(int node, int left, int right){
76+
if (lazy[node] == 0) return;
77+
78+
long k = lazy[node];
79+
// XOR의 특성: 구간 길이가 홀수일 때만 실제로 값이 변함
80+
int rangeLength = right - left + 1;
81+
if (rangeLength % 2 == 1) {
82+
tree[node] ^= k;
83+
}
84+
85+
if (left != right){
86+
lazy[node*2] ^= k;
87+
lazy[node*2+1] ^= k;
88+
}
89+
lazy[node] = 0;
90+
}
91+
92+
public long query(int startIdx, int endIdx){
93+
return query(1,0, size-1, startIdx, endIdx);
94+
}
95+
96+
private long query(int node , int left, int right, int startIdx , int endIdx){
97+
updateLazy(node, left, right);
98+
if ( left > endIdx || right < startIdx) return 0;
99+
if (left >= startIdx && right <= endIdx) return tree[node];
100+
101+
int mid = (left+right)/2;
102+
return query(node*2, left, mid, startIdx, endIdx)^query(node*2+1, mid+1, right, startIdx, endIdx);
103+
}
104+
}
105+
106+
107+
108+
public static void main(String[] args) throws IOException {
109+
init();
110+
process();
111+
print();
112+
}
113+
114+
private static void init() throws IOException {
115+
size = Integer.parseInt(br.readLine());
116+
input = new long[size];
117+
118+
119+
StringTokenizer st = new StringTokenizer(br.readLine());
120+
for (int i = 0; i < size; i++) {
121+
input[i] = Long.parseLong(st.nextToken());
122+
}
123+
124+
queryCnt = Integer.parseInt(br.readLine());
125+
126+
}
127+
128+
private static void process() throws IOException {
129+
130+
SegmentTree tree = new SegmentTree(input);
131+
132+
for (int i = 0; i < queryCnt; i++) {
133+
StringTokenizer st = new StringTokenizer(br.readLine());
134+
int order = Integer.parseInt(st.nextToken());
135+
int start = Integer.parseInt(st.nextToken());
136+
int end = Integer.parseInt(st.nextToken());
137+
138+
139+
if (order == UPDATE) {
140+
long plus = Long.parseLong(st.nextToken());
141+
tree.updateRange(start, end, plus);
142+
} else sb.append(tree.query(start, end)).append("\n");
143+
144+
145+
int power = 2;
146+
for (int j = 1; j < tree.tree.length; j++) {
147+
if (j == power) {
148+
System.out.println();
149+
power *= 2;
150+
}
151+
System.out.print(tree.tree[j] +" ");
152+
}
153+
System.out.println();
154+
155+
156+
power = 2;
157+
for (int j = 1; j < tree.tree.length; j++) {
158+
if (j == power) {
159+
System.out.println();
160+
power *= 2;
161+
}
162+
System.out.print(tree.lazy[j] +" ");
163+
}
164+
System.out.println();
165+
}
166+
167+
}
168+
169+
170+
private static void print() {
171+
System.out.println(sb.toString());
172+
173+
}
174+
}
175+
```
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
```java
2+
3+
import java.io.BufferedReader;
4+
import java.io.IOException;
5+
import java.io.InputStreamReader;
6+
import java.util.StringTokenizer;
7+
8+
9+
public class Main {
10+
11+
12+
static StringBuilder sb = new StringBuilder();
13+
static int cityCnt,planCityCnt;
14+
static int[][] arr;
15+
static int[] plan,parent;
16+
17+
18+
public static void main(String[] args) throws IOException {
19+
init();
20+
process();
21+
print();
22+
}
23+
24+
private static void init() throws IOException {
25+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
26+
cityCnt = Integer.parseInt(br.readLine());
27+
planCityCnt = Integer.parseInt(br.readLine());
28+
arr = new int[cityCnt][cityCnt];
29+
parent = new int[cityCnt];
30+
for (int i = 0; i < cityCnt; i++) {
31+
parent[i] = i;
32+
}
33+
plan = new int[planCityCnt];
34+
35+
for (int i = 0; i < cityCnt; i++) {
36+
StringTokenizer st = new StringTokenizer(br.readLine());
37+
for (int j = 0; j < cityCnt; j++) {
38+
arr[i][j] = Integer.parseInt(st.nextToken());
39+
}
40+
}
41+
42+
StringTokenizer st = new StringTokenizer(br.readLine());
43+
for (int i = 0; i < planCityCnt; i++) {
44+
plan[i] = Integer.parseInt(st.nextToken())-1;
45+
}
46+
47+
}
48+
49+
private static void process() throws IOException {
50+
for (int i = 0; i < cityCnt; i++) {
51+
for (int j = 0; j < cityCnt; j++) {
52+
if (arr[i][j] == 1) union(i,j);
53+
}
54+
}
55+
56+
for (int i = 1; i < planCityCnt; i++) {
57+
int preRoot = find(plan[i-1]);
58+
int curRoot = find(plan[i]);
59+
if (preRoot != curRoot) {
60+
System.out.println("NO");
61+
return;
62+
}
63+
}
64+
65+
System.out.println("YES");
66+
67+
}
68+
69+
private static void union(int a, int b) {
70+
int aRoot = find(a);
71+
int bRoot = find(b);
72+
73+
if (aRoot == bRoot) return;
74+
75+
if (aRoot > bRoot) {
76+
parent[bRoot] = aRoot;
77+
} else {
78+
parent[aRoot] = bRoot;
79+
}
80+
81+
}
82+
83+
private static int find(int x) {
84+
if (x == parent[x]) return x;
85+
86+
return parent[x] = find(parent[x]);
87+
}
88+
89+
90+
91+
private static void print() {
92+
System.out.print(sb.toString());
93+
}
94+
}
95+
```

0 commit comments

Comments
 (0)