Skip to content

Commit 4db9213

Browse files
committed
Merge branch 'taunt_eval'
# Conflicts: # src/main/java/main/java/hackerearth/taunt/Taunt.java # src/main/java/main/java/hackerearth/taunt/TauntTest.java
2 parents c637c89 + 33de4ed commit 4db9213

File tree

5 files changed

+384
-198
lines changed

5 files changed

+384
-198
lines changed

src/main/java/main/java/codechef/DISTNUM3.java

Lines changed: 124 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,24 @@
55
import java.util.*;
66
import java.io.*;
77

8+
/**
9+
* Reference: https://www.codechef.com/viewsolution/12879967
10+
*/
811
public class DISTNUM3 {
9-
private static final int MAX = 100000;
10-
static ArrayList<Integer>[] adj;
11-
static int clock = 0, eulerTour[], start[], end[], V;
12-
static int BLOCK_SIZE;
13-
14-
/* LCA <NlogN , logN> dependency : level , log , V , DP = new int[log(V) + 1][V + 1];, parent (for the first level of DP) */
12+
static List<Integer>[] adj;
13+
static int clock = 0, start[], end[], V;
1514
static int DP[][];
1615
static int level[];
1716
static int parent[];
17+
static int distinctCount;
18+
static boolean marked[];
19+
static int vertices[];
1820

1921
static int log(int N) {
2022
return 31 - Integer.numberOfLeadingZeros(N);
2123
}
2224

23-
static void binaryLift() {
25+
static void findAncestorsAtEachLevel() {
2426
System.arraycopy(parent, 1, DP[0], 1, V);
2527
for (int i = 1; i < DP.length; i++) {
2628
for (int j = 1; j <= V; j++) {
@@ -31,247 +33,204 @@ static void binaryLift() {
3133

3234
static int LCA(int u, int v) {
3335
if (level[v] < level[u]) {
34-
int temp = u;
36+
final int temp = u;
3537
u = v;
3638
v = temp;
3739
}
3840
int diff = level[v] - level[u];
39-
while (diff > 0) { // Bring v to the same level as u
40-
int log = log(diff);
41+
while (diff > 0) {
42+
final int log = log(diff);
4143
v = DP[log][v];
4244
diff -= (1 << log);
4345
}
4446
while (u != v) {
4547
int i = log(level[u]);
46-
for (; i > 0 && DP[i][u] == DP[i][v]; )
48+
while (i > 0 && DP[i][u] == DP[i][v]) {
4749
i--;
48-
50+
}
4951
u = DP[i][u];
5052
v = DP[i][v];
5153
}
52-
5354
return u;
5455
}
5556

56-
static void dfs(int u, int par, int lev) {
57+
static void dfs(final int u, final int par, final int lev, final int[] eulerTour) {
5758
eulerTour[clock] = u;
5859
start[u] = clock++;
5960
parent[u] = par;
6061
level[u] = lev;
61-
for (int v : adj[u])
62-
if (v != par)
63-
dfs(v, u, lev + 1);
64-
62+
for (final int v : adj[u]) {
63+
if (v != par) {
64+
dfs(v, u, lev + 1, eulerTour);
65+
}
66+
}
6567
eulerTour[clock] = u;
6668
end[u] = clock++;
6769
}
6870

69-
70-
static class Query {
71-
int L, R, numUpdatesLess, LCA, id;
72-
73-
public Query(int l, int r, int numUpdatesLess, int lCA, int id) {
74-
L = l;
75-
R = r;
76-
this.numUpdatesLess = numUpdatesLess;
77-
LCA = lCA;
78-
this.id = id;
79-
}
80-
81-
@Override
82-
public String toString() {
83-
return String.format("[L = %d R = %d updatesLess = %d LCA = %d id = %d]", L, R, numUpdatesLess, LCA, id);
84-
}
85-
}
86-
87-
static class Update {
88-
int idx, prevVal, newVal;
89-
90-
public Update(int idx, int newVal, int prevVal) {
91-
this.idx = idx;
92-
this.newVal = newVal;
93-
this.prevVal = prevVal;
94-
}
95-
96-
@Override
97-
public String toString() {
98-
return String.format("[idx = %d prevVal = %d newVal = %d", idx, prevVal, newVal);
99-
}
100-
}
101-
102-
static class MoComparator implements Comparator<Query> {
103-
@Override
104-
public int compare(Query o1, Query o2) {
105-
if (blockCache[o1.L] != blockCache[o2.L])
106-
return blockCache[o1.L] - blockCache[o2.L];
107-
else if (blockCache[o1.R] != blockCache[o2.R])
108-
return blockCache[o1.R] - blockCache[o2.R];
109-
else
110-
return o1.numUpdatesLess - o2.numUpdatesLess;
111-
}
112-
}
113-
114-
static int freq[];
115-
static int distinctCount;
116-
static boolean marked[];
117-
static int blockCache[];
118-
static int val[];
119-
static HashMap<Integer, Integer> map;
120-
121-
static void visit(int idx) {
71+
static void visit(final int idx, final int[] frequency) {
12272
if (marked[idx]) {
123-
freq[val[idx]]--;
124-
if (freq[val[idx]] == 0)
73+
frequency[vertices[idx]]--;
74+
if (frequency[vertices[idx]] == 0) {
12575
distinctCount--;
76+
}
12677
} else {
127-
freq[val[idx]]++;
128-
if (freq[val[idx]] == 1)
78+
frequency[vertices[idx]]++;
79+
if (frequency[vertices[idx]] == 1) {
12980
distinctCount++;
81+
}
13082
}
131-
13283
marked[idx] = !marked[idx];
13384
}
13485

135-
static void update(int idx, int newVal) {
86+
static void update(final int idx, final int newVal, final int[] frequency) {
13687
if (marked[idx]) {
137-
visit(idx);
138-
val[idx] = newVal;
139-
visit(idx);
140-
} else
141-
val[idx] = newVal;
142-
}
143-
144-
static int countDistinct(int u, int v) {
145-
int lca = LCA(u, v);
146-
BitSet bitSet = new BitSet(map.size());
147-
bitSet.set(val[lca]);
148-
while (u != lca) {
149-
bitSet.set(val[u]);
150-
u = parent[u];
151-
}
152-
while (v != lca) {
153-
bitSet.set(val[v]);
154-
v = parent[v];
88+
visit(idx, frequency);
89+
vertices[idx] = newVal;
90+
visit(idx, frequency);
91+
} else {
92+
vertices[idx] = newVal;
15593
}
156-
157-
return bitSet.cardinality();
15894
}
15995

16096
public static void main(String[] args) throws IOException {
16197
final InputReader in = new InputReader(System.in);
162-
int qSZ = 0, uSZ = 0;
16398
V = in.readInt();
164-
int Q = in.readInt();
165-
int E = V - 1;
166-
Query queries[] = new Query[MAX];
167-
Update updates[] = new Update[MAX];
168-
map = new HashMap<>(); // Used to compress the keys
169-
99+
final int Q = in.readInt();
170100
adj = new ArrayList[V + 1];
171101
for (int i = 1; i <= V; i++) {
172102
adj[i] = new ArrayList<>();
173103
}
174-
val = new int[V + 1];
104+
vertices = new int[V + 1];
175105
for (int i = 1; i <= V; i++) {
176-
val[i] = in.readInt();
106+
vertices[i] = in.readInt();
177107
}
108+
final Map<Integer, Integer> map = new HashMap<>();
178109
for (int i = 1; i <= V; i++) {
179-
if (!map.containsKey(val[i])) {
180-
map.put(val[i], map.size());
181-
}
182-
val[i] = map.get(val[i]);
110+
map.putIfAbsent(vertices[i], map.size());
111+
vertices[i] = map.get(vertices[i]);
183112
}
184-
int currVal[] = new int[V + 1];
185-
System.arraycopy(val, 0, currVal, 0, V + 1);
186-
while (E-- > 0) {
113+
final int verticesCopy[] = new int[V + 1];
114+
System.arraycopy(vertices, 0, verticesCopy, 0, V + 1);
115+
final int edges = V - 1;
116+
for (int i = 0; i < edges; i++) {
187117
final int u = in.readInt();
188118
final int v = in.readInt();
189119
adj[u].add(v);
190120
adj[v].add(u);
191121
}
192122
start = new int[V + 1];
193123
end = new int[V + 1];
194-
eulerTour = new int[2 * (V + 1)];
124+
final int[] eulerTour = new int[2 * (V + 1)];
195125
level = new int[V + 1];
196126
marked = new boolean[V + 1];
197127
DP = new int[log(V) + 1][V + 1];
198128
parent = new int[V + 1];
199-
blockCache = new int[2 * (V + 1)];
200-
dfs(1, 0, 0);
201-
binaryLift();
202-
while (Q-- > 0) {
203-
if (in.readInt() == 1) { // Query
129+
dfs(1, 0, 0, eulerTour);
130+
findAncestorsAtEachLevel();
131+
int numberOfQueries = 0, numberOfUpdates = 0;
132+
final Query queries[] = new Query[Q];
133+
final Update updates[] = new Update[Q];
134+
for (int i = 0; i < Q; i++) {
135+
if (in.readInt() == 1) {
204136
final int u = in.readInt();
205137
final int v = in.readInt();
206138
final Query q;
207-
if (end[u] < start[v]) // Cousin Nodes
208-
{
209-
q = new Query(end[u], start[v], uSZ, LCA(u, v), qSZ);
139+
if (start[v] > end[u]) {
140+
q = new Query(end[u], start[v], numberOfUpdates, LCA(u, v), numberOfQueries);
210141
} else if (start[u] > end[v]) {
211-
q = new Query(end[v], start[u], uSZ, LCA(u, v), qSZ);
212-
} else // Ancestors
213-
{
214-
q = new Query(Math.min(start[u], start[v]), Math.max(start[u], start[v]), uSZ, -1, qSZ);
142+
q = new Query(end[v], start[u], numberOfUpdates, LCA(u, v), numberOfQueries);
143+
} else {
144+
q = new Query(Math.min(start[u], start[v]),
145+
Math.max(start[u], start[v]),
146+
numberOfUpdates,
147+
-1,
148+
numberOfQueries);
215149
}
216-
queries[qSZ++] = q;
150+
queries[numberOfQueries++] = q;
217151
} else {
218152
final int idx = in.readInt();
219153
int newVal = in.readInt();
220-
if (!map.containsKey(newVal)) {
221-
map.put(newVal, map.size());
222-
}
154+
map.putIfAbsent(newVal, map.size());
223155
newVal = map.get(newVal);
224-
updates[uSZ++] = new Update(idx, newVal, currVal[idx]);
225-
currVal[idx] = newVal;
156+
updates[numberOfUpdates++] = new Update(idx, newVal, verticesCopy[idx]);
157+
verticesCopy[idx] = newVal;
226158
}
227159
}
228-
freq = new int[map.size()];
229-
BLOCK_SIZE = (int) (Math.pow(2 * V, 2.0 / 3.0) + 1);
230-
for (int i = 0; i < blockCache.length; i++) {
231-
blockCache[i] = i / BLOCK_SIZE;
232-
}
233-
Arrays.sort(queries, 0, qSZ, new MoComparator());
234-
final int ans[] = new int[qSZ];
160+
final int BLOCK_SIZE = (int) (Math.pow(2 * V, 2.0 / 3.0) + 1);
161+
Arrays.sort(queries, 0, numberOfQueries, (first, second) -> {
162+
if (first.L / BLOCK_SIZE != second.L / BLOCK_SIZE) {
163+
return first.L / BLOCK_SIZE - second.L / BLOCK_SIZE;
164+
} else if (first.R / BLOCK_SIZE != second.R / BLOCK_SIZE) {
165+
return first.R / BLOCK_SIZE - second.R / BLOCK_SIZE;
166+
} else {
167+
return first.updatesTillNow - second.updatesTillNow;
168+
}
169+
});
170+
final int ans[] = new int[numberOfQueries];
235171
int moLeft = -1, moRight = -1;
236-
int currUpd = 0;
237-
for (int i = 0; i < qSZ; i++) {
238-
final Query q = queries[i];
239-
while (currUpd < q.numUpdatesLess) {
240-
final Update u = updates[currUpd];
241-
update(u.idx, u.newVal);
242-
currUpd++;
172+
int currentUpdateCount = 0;
173+
final int[] frequency = new int[map.size()];
174+
for (int i = 0; i < numberOfQueries; i++) {
175+
final Query query = queries[i];
176+
while (currentUpdateCount < query.updatesTillNow) {
177+
final Update update = updates[currentUpdateCount++];
178+
update(update.idx, update.newValue, frequency);
243179
}
244-
while (currUpd > q.numUpdatesLess) {
245-
final Update u = updates[currUpd - 1];
246-
update(u.idx, u.prevVal);
247-
currUpd--;
180+
while (currentUpdateCount > query.updatesTillNow) {
181+
final Update update = updates[--currentUpdateCount];
182+
update(update.idx, update.previousValue, frequency);
248183
}
249-
while (moLeft < q.L - 1) {
184+
while (moLeft < query.L - 1) {
250185
moLeft++;
251-
visit(eulerTour[moLeft]);
186+
visit(eulerTour[moLeft], frequency);
252187
}
253-
while (moLeft >= q.L) {
254-
visit(eulerTour[moLeft]);
188+
while (moLeft >= query.L) {
189+
visit(eulerTour[moLeft], frequency);
255190
moLeft--;
256191
}
257-
while (moRight < q.R) {
192+
while (moRight < query.R) {
258193
moRight++;
259-
visit(eulerTour[moRight]);
194+
visit(eulerTour[moRight], frequency);
260195
}
261-
while (moRight > q.R) {
262-
visit(eulerTour[moRight]);
196+
while (moRight > query.R) {
197+
visit(eulerTour[moRight], frequency);
263198
moRight--;
264199
}
265-
if (q.LCA != -1) {
266-
visit(q.LCA);
200+
if (query.LCA != -1) {
201+
visit(query.LCA, frequency);
267202
}
268-
ans[q.id] = distinctCount;
269-
if (q.LCA != -1) {
270-
visit(q.LCA);
203+
ans[query.id] = distinctCount;
204+
if (query.LCA != -1) {
205+
visit(query.LCA, frequency);
271206
}
272207
}
208+
final StringBuilder stringBuilder = new StringBuilder();
273209
for (final int a : ans) {
274-
System.out.println(a);
210+
stringBuilder.append(a).append('\n');
275211
}
212+
System.out.println(stringBuilder);
213+
}
214+
}
215+
216+
class Query {
217+
final int L, R, updatesTillNow, LCA, id;
218+
219+
public Query(final int l, final int r, final int updatesTillNow, final int lCA, final int id) {
220+
L = l;
221+
R = r;
222+
this.updatesTillNow = updatesTillNow;
223+
LCA = lCA;
224+
this.id = id;
225+
}
226+
}
227+
228+
class Update {
229+
final int idx, previousValue, newValue;
230+
231+
public Update(final int idx, final int newValue, final int previousValue) {
232+
this.idx = idx;
233+
this.newValue = newValue;
234+
this.previousValue = previousValue;
276235
}
277-
}
236+
}

0 commit comments

Comments
 (0)