lazylazylazylazylazylazylazylazy

백준[JAVA] 9345번 디지털 비디오 디스크(DVDs) 본문

프로그래밍/Break BOJ byJAVA

백준[JAVA] 9345번 디지털 비디오 디스크(DVDs)

lazylazylazylazylazylazylazylazy 2023. 2. 22. 19:55
728x90
반응형

https://www.acmicpc.net/problem/9345

 

9345번: 디지털 비디오 디스크(DVDs)

손님이 DVD를 카운터에 가져왔을 때 손님이 원하는 DVD가 전부 존재하면, (A번 선반부터 B번 선반까지에 있는 DVD를 전부 가져왔을 때 순서에 상관없이 A번 DVD부터 B번 DVD까지 있다면) "YES"를 출력하

www.acmicpc.net

요새 세그먼트 트리만 풀고있는데 좋은 문제를 발견하여 풀이를 공유합니다!

 

 

전형적인 세그먼트트리 문제입니다. 

i와 k가 주어진다면 A[i]~A[k] 범위에서 순서에 상관없이 범위내의 숫자가 존재하는지 물어보는 문제입니다!

혼자 처음에는 어떻게 풀어야하나 고민을 많이 했습니다.

머지소트트리 문제처럼 각 노드의 부모를 노드끼리 리스트로 만들어서 확인할려했지만 너무 배보다 배꼽이 큰거같아 

포기했습니다.

그러다가  a~b 범위내 숫자가 모두 존재할려면 최솟값이 a,최댓값이 b면 된다는 아이디어가 떠올라서

최소세그먼트트리와 최대세그먼트트리를 이용하여 문제를 풀었습니다.

예를 들어 2~5 범위에 2,3,4,5가 모두 존재할려면 2~5의 최솟값은 2 최대값은 5이면 됩니다. 만일 3이 아니라 7이면 최대값이 7이되므로 NO가 되기때문입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
package main;
 
 
import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;
 
import java.util.List;
class Main {
    static int size;
    static int first;
    static int[] mintree;
    static int[] maxtree;
    static int[] minarr;
    static int[] maxarr;
    static int logn;
    public static void main(String[] args) throws IOException {
        
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        int test=Integer.parseInt(br.readLine());
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<test;i++) {
            StringTokenizer st=new StringTokenizer(br.readLine());
            size= Integer.parseInt(st.nextToken());
            int line=Integer.parseInt(st.nextToken());
            logn=0;
            for(int j=1;j<size;j*=2) {
                logn++;
                
            }
            
            minarr=new int[size+1];
            maxarr=new int[size+1];
            minarr[size]=Integer.MAX_VALUE;
            
            maxarr[size]=Integer.MIN_VALUE;
            mintree=new int[(int)Math.pow(2, logn+1)];
            maxtree=new int[mintree.length];
            Arrays.fill(mintree, size);
            Arrays.fill(maxtree, size);
            first=mintree.length/2;
            
            for(int j=0;j<size;j++) {
                minarr[j]=j;
                maxarr[j]=j;
                mintree[first+j]=j;
                maxtree[first+j]=j;
            }
            
            mininit(1);
            maxinit(1);
            for(int j=0;j<line;j++) {
                st=new StringTokenizer(br.readLine());
                int choice=Integer.parseInt(st.nextToken());
                
                if(choice==0) {
                    int temp1=Integer.parseInt(st.nextToken());
                    int answer1=minarr[temp1];
                    int temp2=Integer.parseInt(st.nextToken());
                    int answer2=minarr[temp2];
                    minarr[temp1]=answer2;
                    minarr[temp2]=answer1;
                    maxarr[temp1]=answer2;
                    maxarr[temp2]=answer1;
                    minupdate(first+temp1);
                    minupdate(first+temp2);
                    maxupdate(first+temp1);
                    maxupdate(first+temp2);
                }
                else {
                    int temp1=Integer.parseInt(st.nextToken());
                    int temp2=Integer.parseInt(st.nextToken());
                    int result1=minarr[minfind(first+temp1, first+temp2)];
                    int result2=maxarr[maxfind(first+temp1, first+temp2)];
                    if(result1==temp1&&result2==temp2) {
                        sb.append("YES").append("\n");
                    }else sb.append("NO").append("\n");
                }
                
                
                
            }
            
        
            
            
            
            
            
            
        }
        System.out.println(sb);
        
        
    }
    static int maxfind(int start, int end) {
        int result=maxtree[start];
        while(end>=start) {
            if(end==start) {
                if(maxarr[result]<maxarr[maxtree[start]]) {
                     result=maxtree[start];
                }
                return result;
            }
            if(start%2==1) {
                if(maxarr[result]<maxarr[maxtree[start]]) {
                result=maxtree[start];
                }
                start++;
            }
            if(end%2==0) {
                if(maxarr[result]<maxarr[maxtree[end]]) {
                result=maxtree[end];
                }
                end--;
            }
            start/=2;
            end/=2;
        }
        return result;
    }
    static int minfind(int start,int end) {
        int result=mintree[start];
        while(end>=start) {
            if(end==start) {
                if(minarr[result]>minarr[mintree[start]]) {
                    return result=mintree[start];
                }
            }
            if(start%2==1) {
                if(minarr[result]>minarr[mintree[start]]) {
                result=mintree[start];
                }
                start++;
            }
            if(end%2==0) {
                if(minarr[result]>minarr[mintree[end]]) {
                result=mintree[end];
                }
                end--;
            }
            start/=2;
            end/=2;
        }
        return result;
    }
    static void maxupdate(int index) {
        int temp=index/2;
        while(temp!=0) {
        if(maxarr[maxtree[temp*2]]>=maxarr[maxtree[temp*2+1]]) {
             maxtree[temp]=maxtree[temp*2];
        }else  maxtree[temp]=maxtree[temp*2+1];
        temp/=2;}
    }
    static void minupdate(int index) {
        int temp=index/2;
        while(temp!=0) {
            if(minarr[mintree[temp*2]]<=minarr[mintree[temp*2+1]]) {
                 mintree[temp]=mintree[temp*2];
            }else  mintree[temp]=mintree[temp*2+1];
 
            
            temp/=2;
        }
    }
    static int mininit(int index) {
        if(index>=first/2) {
            if(minarr[mintree[index*2]]<=minarr[mintree[index*2+1]]) {
                return mintree[index]=mintree[index*2];
            }else return mintree[index]=mintree[index*2+1];
            
        }
        if(minarr[mininit(index*2)]<=minarr[mininit(index*2+1)]) {
            
            return mintree[index]=mintree[index*2];
        }else return mintree[index]=mintree[index*2+1];
        
    }
    static int maxinit(int index) {
        if(index>=first/2) {
            if(maxarr[maxtree[index*2]]>=maxarr[maxtree[index*2+1]]) {
                return maxtree[index]=maxtree[index*2];
            }else return maxtree[index]=maxtree[index*2+1];
            
        }
        if(maxarr[maxinit(index*2)]>=maxarr[maxinit(index*2+1)]) {
            
            return maxtree[index]=maxtree[index*2];
        }else return maxtree[index]=maxtree[index*2+1];
        
    }
    
    
    }
 
 
 
 
 
 
 
cs

 

 

최소세그먼트트리 최대세그먼트트리를 만들어 준후 0일때는 값을 바꿔주고 바뀐 인덱스끼리 범위에서 다시 트리를 업데이트 해줬습니다

1일때는 범위내에 최대값 최소값을 찾아주어 문제를 해결하였습니다.

더 좋은 풀이가 있으면 댓글달아주세요!!!!감사합니다

728x90
반응형
Comments