Skip to content

Commit f9156b6

Browse files
authored
Merge pull request #852 from AlgorithmWithGod/khj20006
[20250909] BOJ / P2 / Double Up 2 / 권혁준
2 parents 722c257 + d01fd41 commit f9156b6

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
```java
2+
import java.io.*;
3+
import java.util.*;
4+
5+
class IOController {
6+
BufferedReader br;
7+
BufferedWriter bw;
8+
StringTokenizer st;
9+
10+
public IOController() {
11+
br = new BufferedReader(new InputStreamReader(System.in));
12+
bw = new BufferedWriter(new OutputStreamWriter(System.out));
13+
st = new StringTokenizer("");
14+
}
15+
16+
String nextLine() throws Exception {
17+
String line = br.readLine();
18+
st = new StringTokenizer(line);
19+
return line;
20+
}
21+
22+
String nextToken() throws Exception {
23+
while (!st.hasMoreTokens())
24+
nextLine();
25+
return st.nextToken();
26+
}
27+
28+
int nextInt() throws Exception {
29+
return Integer.parseInt(nextToken());
30+
}
31+
32+
long nextLong() throws Exception {
33+
return Long.parseLong(nextToken());
34+
}
35+
36+
double nextDouble() throws Exception {
37+
return Double.parseDouble(nextToken());
38+
}
39+
40+
void close() throws Exception {
41+
bw.flush();
42+
bw.close();
43+
}
44+
45+
void write(String content) throws Exception {
46+
bw.write(content);
47+
}
48+
49+
}
50+
51+
public class Main {
52+
53+
static IOController io;
54+
55+
//
56+
57+
static int N, M;
58+
static int[] next, root, indeg;
59+
static long[] cnt, origin;
60+
static List<List<Integer>> cycles;
61+
static boolean[] isCycle;
62+
63+
static int f(int x) {return x==root[x] ? x : (root[x]=f(root[x]));}
64+
65+
public static void main(String[] args) throws Exception {
66+
67+
io = new IOController();
68+
69+
N = io.nextInt();
70+
M = io.nextInt();
71+
next = new int[M];
72+
origin = new long[M];
73+
root = new int[M];
74+
cnt = new long[M];
75+
indeg = new int[M];
76+
for(int i=0;i<M;i++) root[i] = i;
77+
for(int i=0;i<M;i++) {
78+
next[i] = (i*2)%M;
79+
indeg[next[i]]++;
80+
int x = f(i), y = f(next[i]);
81+
if(x != y) root[x] = y;
82+
}
83+
for(int i=0;i<N;i++) cnt[io.nextInt()]++;
84+
85+
cycles = new ArrayList<>();
86+
boolean[] vis = new boolean[M];
87+
boolean[] vvis = new boolean[M];
88+
int[] par = new int[M];
89+
for(int i=0;i<M;i++) if(!vis[f(i)]) {
90+
vis[f(i)] = true;
91+
int n = i;
92+
vvis[n] = true;
93+
while(!vvis[next[n]]) {
94+
par[next[n]] = n;
95+
n = next[n];
96+
vvis[n] = true;
97+
}
98+
List<Integer> list = new ArrayList<>();
99+
int r = next[n];
100+
list.add(r);
101+
while(n != r) {
102+
list.add(n);
103+
n = par[n];
104+
}
105+
cycles.add(list);
106+
}
107+
108+
isCycle = new boolean[M];
109+
for(List<Integer> list : cycles) {
110+
for(int i:list) isCycle[i] = true;
111+
}
112+
113+
Queue<Integer> q = new ArrayDeque<>();
114+
for(int i=0;i<M;i++) if(indeg[i] == 0) q.add(i);
115+
while(!q.isEmpty()) {
116+
int n = q.poll();
117+
origin[next[n]] += origin[n] + cnt[n];
118+
cnt[next[n]] += cnt[n];
119+
if(!isCycle[next[n]]) {
120+
if(--indeg[next[n]] == 0) q.add(next[n]);
121+
}
122+
}
123+
124+
long ans = Long.MAX_VALUE, S = 0;
125+
for(List<Integer> list : cycles) {
126+
long sum = 0, s = 0;
127+
int zeroCnt = 0;
128+
for(int i=0;i<list.size();i++) {
129+
if(cnt[list.get(i)] == 0) zeroCnt++;
130+
sum += (long)i * cnt[list.get(i)];
131+
s += cnt[list.get(i)];
132+
}
133+
if(s < S) continue;
134+
135+
if(zeroCnt == list.size()-1) {
136+
int nonzeroNum = 0;
137+
for(int i:list) if(cnt[i] != 0) nonzeroNum = i;
138+
139+
long res = Long.MAX_VALUE;
140+
for(int i=0;i<M;i++) if(f(i) == f(nonzeroNum)) {
141+
if(cnt[i] == s) res = Math.min(res, origin[i]);
142+
}
143+
144+
if(s > S) ans = res;
145+
else ans = Math.min(ans, res);
146+
S = s;
147+
continue;
148+
}
149+
150+
long res = sum;
151+
for(int i=0;i<list.size()-1;i++) {
152+
sum += (long)list.size() * cnt[list.get(i)] - s;
153+
res = Math.min(res, sum);
154+
}
155+
156+
long orgsum = 0;
157+
for(int i:list) {
158+
orgsum += origin[i];
159+
}
160+
res += orgsum;
161+
162+
if(s > S) ans = res;
163+
else ans = Math.min(ans, res);
164+
S = s;
165+
}
166+
167+
io.write(S + " " + ans + "\n");
168+
169+
io.close();
170+
171+
}
172+
173+
}
174+
```

0 commit comments

Comments
 (0)