Skip to content

Commit dd98136

Browse files
authored
Add files via upload
1 parent 6c7910c commit dd98136

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-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+
```

0 commit comments

Comments
 (0)