Skip to main content

Placements '24: Assessments [Part 2]

Image of the author

Eshaan Aggarwal @EshaanAgg

This is the second part of the series on online assessments that I witnessed during the season of 2024. The first part can be found here.


Zomato

Other Campuses Questions

  1. You are given the edges that form a tree with the root as 00. A traversal of the tree is generated in the following manner:

    • An empty queue qq is initialized and the node 00 is pushed into it.
    • While the queue is not empty, the front element is popped and all its children are pushed into the queue in any arbitary order.
    • The popped element is added to the traversal.

    You are given multiple traversals of the tree, and you need to find which of the traversals provided can be a valid BFS order traversal of the same.

    Solution

    We can use the provided traversal to order the nodes of the tree in the particular order. We can then generate the BFS traversal of the tree and compare it with the provided traversal.

    Time Complexity: O(QNlogN)O(Q * N \log N)

    1
    bool checkTraversal(int n, vector<vector<int>> &g, vector<int> &traversal) {
    2
    if (traversal.size() != n)
    3
    return false;
    4
    5
    vector<int> idx(n, -1);
    6
    for (int i = 0; i < n; i++)
    7
    idx[traversal[i]] = i;
    8
    for (int i = 0; i < n; i++)
    9
    if (idx[i] == -1)
    10
    return false;
    11
    12
    for (auto &ch: g)
    13
    sort(ch.begin(), ch.end(), [&](int a, int b) {
    14
    return idx[a] < idx[b];
    15
    });
    16
    17
    queue<int> q;
    18
    q.push(0);
    19
    vector<int> tr;
    20
    while (!q.empty()) {
    21
    int u = q.front();
    22
    q.pop();
    23
    tr.push_back(u);
    24
    for (auto &v: g[u])
    25
    q.push(v);
    26
    }
    27
    28
    return tr == traversal;
    29
    }
    30
    31
    vector<bool> show(vector<vector<int>> edges, vector<vector<int>> traversals) {
    32
    int n = edges.size() + 1;
    33
    34
    vector<vector<int>> g(n);
    35
    for (auto &e : edges) {
    36
    g[e[0]].push_back(e[1]);
    37
    g[e[1]].push_back(e[0]);
    38
    }
    39
    40
    vector<bool> ans;
    41
    for (auto &tr : traversals)
    42
    ans.push_back(checkTraversal(n, g, tr));
    43
    44
    return ans;
    45
    }
  2. You are given an string ss. You are also given two strings tt and uu which are both initially empty. You can perform either of the two operations in a turn:

    • Append the first character of ss to the end of tt.
    • Append the last character of tt to the end of uu.

    You need to apply these operations such that all the end all the characters from ss are shifted to uu, and the generated string uu is the lexicographically smallest possible. Return the lexicographically smallest string uu that can be generated.

    Solution

    This question can be solved with the help of stack and using a greedy approach. In the stack, we try to maintain all the elements that we can processed till now (it acts like our string tt). We greedily process the characters from aa to zz, always travelling to their rightmost occurence and trying to add them to the string uu. Before processing any character, we also check our stack to see it has some smaller character than the current one, and if it does, we pop it out and add it to the string uu.

    Time Complexity: O(N)O(N) where NN is the length of the string ss.

    1
    string solve(string s)
    2
    {
    3
    int n = s.size();
    4
    5
    vector<int> lastOccur(26, -1);
    6
    for (int i = 0; i < n; i++)
    7
    lastOccur[s[i] - 'a'] = i;
    8
    9
    stack<char> st;
    10
    string ans = "";
    11
    12
    int lastIdx = -1;
    13
    for (char cur = 'a'; cur <= 'z'; cur++)
    14
    {
    15
    if (lastOccur[cur - 'a'] == -1 || lastOccur[cur - 'a'] <= lastIdx)
    16
    continue;
    17
    18
    while (!st.empty() && st.top() <= cur)
    19
    {
    20
    ans += st.top();
    21
    st.pop();
    22
    }
    23
    24
    while (lastIdx < lastOccur[cur - 'a'])
    25
    {
    26
    lastIdx++;
    27
    if (s[lastIdx] == cur)
    28
    ans += cur;
    29
    else
    30
    st.push(s[lastIdx]);
    31
    }
    32
    }
    33
    34
    while (!st.empty())
    35
    {
    36
    ans += st.top();
    37
    st.pop();
    38
    }
    39
    40
    return ans;
    41
    }
  3. You are given a string ss that has lowercase English characters. You are also given an integer nn. You need to generate a string xx of the given length nn such that:

    • All of the distinct characters present in ss must be present in the string xx.
    • We will then make a string tt by repeatedly adding the string xx to it untill the string tt can be rearranged to have the string ss as a substring.
    • The generated string tt should be of the minimum possible length.
    • If there are multiple possible tt with the same length, the string xx should be chosen so that the generated string tt is the lexicographically smallest possible.

    Return the string xx that would generate the string tt. Return empty string if no such string xx exists.

    Solution

    It is clear that we need to minimse the number of copies of the string xx that we need to add to the string tt. We can binary search on this value of copies needed, and then generate the string xx greedily by adding the minimum number of characters needed to fullfill condition 22, and pad the rest of the spaces with the character aa.

    Time Complexity: O(N+26logN)O(N + 26 \log N) where NN is the length of the string ss.

    1
    bool canGenerate(int copies, int n, vector<int> &cnt)
    2
    {
    3
    int total = 0;
    4
    for (int i = 0; i < 26; i++)
    5
    total += (cnt[i] + copies - 1) / copies;
    6
    return total <= n;
    7
    }
    8
    9
    string generate(int n, string s)
    10
    {
    11
    vector<int> neededCnt(26, 0);
    12
    for (char ch : s)
    13
    neededCnt[ch - 'a']++;
    14
    15
    int l = 0, r = s.size();
    16
    int minCopies = -1;
    17
    while (l <= r)
    18
    {
    19
    int mid = (l + r) / 2;
    20
    if (canGenerate(mid, n, neededCnt))
    21
    {
    22
    minCopies = mid;
    23
    r = mid - 1;
    24
    }
    25
    else
    26
    l = mid + 1;
    27
    }
    28
    29
    if (minCopies == -1)
    30
    return "";
    31
    32
    int usedSpaces = 0;
    33
    vector<int> usedCnt(26, 0);
    34
    for (int i = 0; i < 26; i++)
    35
    {
    36
    usedCnt[i] = (neededCnt[i] + minCopies - 1) / minCopies;
    37
    usedSpaces += usedCnt[i];
    38
    }
    39
    usedCnt[0] += n - usedSpaces;
    40
    41
    string ans = "";
    42
    for (int i = 0; i < 26; i++)
    43
    ans += string(usedCnt[i], 'a' + i);
    44
    45
    return ans;
    46
    }

PACE Stock Broking

Other Campus Questions

  1. There are nn employees in a company, out of which there are kk special employees who have data network and share their mobile hotspots with other employees. There are employee edges connections already made between the employees, where the / connection connects the employees from[i]from[i] and to[i]to[i], such that either of the employees, from[i]from[i] and to[i]to[i] can share a mobile hotspot.

    Two employees xx and yy are connected if there is a path between them. All the employees connected to a special employee xx will use the mobile hotspot of the special employee xx.

    Up to now, to restrict data usage, any employee was connected to at most one special employee. As data consumption has increased, any employee can be connected to at most mm number of special employees. Find the maximum number of edges that can be added to the graph such that any employee is connected to at most mm special employees.

    Solution

    It can be proven that it is optimal to greedily make a component as large as possible. To do the same, we will perform the following steps:

    • Perform a BFS on the graph to find the connected components.
    • For each connected component that has no special employee, connect it to the largest connected component that has a special employee.
    • Sort all the connected components in decreasing order of their size.
    • If the components are c1,c2,,ckc_1, c_2, \ldots, c_k, then connect the first mm components (i.e. c1,c2,,cmc_1, c_2, \ldots, c_m), then the next mm components (i.e. cm+1,cm+2,,c2mc_{m + 1}, c_{m + 2}, \ldots, c_{2m}), and so on.

    Now each component with size ss contribute s(s+1)2x\frac{s \cdot (s + 1)}{2} - x to the answer, where xx is the number of edges present originally in that component. The time complexity of the solution is O(n+m)O(n + m).

  2. A simple variation of Minimum Path Sum

  3. A simple variation of the Job Scheduling Problem

  4. Find the number of ways to colour a 3×n3 \times n grid using 33 colours such that no row and column has all the colours the same. Print the answer modulo 109+710^9 + 7.

    Solution

    Refer to this blog post.

  5. The floor of your house is created by nn tiles, which are either empty (.), dirty (D) or have food (F). Your task is to group the food into a single consecuive group while following the following rules:

    • You can move the food to the left or right by one tile at cost xx.
    • Food can’t be moved to a tile that is dirty.
    • The cost to clean a dirty tile is yy.

    Given qq queries, each all of the form (x,y)(x, y) and a string representing the floor, find the minimum cost to group all the food together for each query.

    Solution

    This is an application of the standard problem trying to group people together, along with the realization of the fact that all the dirty spots between the leftmost food point and the righmost food point must be cleaned. The complexity of the solution is O(n+q)O(n + q).

    1
    int main()
    2
    {
    3
    int n;
    4
    string s;
    5
    cin >> n >> s;
    6
    7
    int firstFood = -1, lastFood = -1;
    8
    for (int i = 0; i < n; i++)
    9
    if (s[i] == 'F')
    10
    {
    11
    if (firstFood == -1)
    12
    firstFood = i;
    13
    lastFood = i;
    14
    }
    15
    16
    int countDirty = 0, countFood = 0;
    17
    for (int i = firstFood; i <= lastFood; i++)
    18
    if (s[i] == 'D')
    19
    {
    20
    countDirty++;
    21
    s[i] = '.';
    22
    }
    23
    else if (s[i] == 'F')
    24
    countFood++;
    25
    26
    int minMoves = 0;
    27
    int seenLeft = 0;
    28
    for (int i = firstFood; i <= lastFood; i++)
    29
    {
    30
    if (s[i] == '.')
    31
    minMoves += min(seenLeft, countFood - seenLeft);
    32
    else
    33
    seenLeft++;
    34
    }
    35
    36
    int q;
    37
    cin >> q;
    38
    while (q--)
    39
    {
    40
    long long x, y;
    41
    cin >> x >> y;
    42
    cout << x * minMoves + y * countDirty << endl;
    43
    }
    44
    }
  6. There are infinite seats in a bus. There are nn people in a queue waiting to board the bus, and each wants to board and sit as seat arr[i]arr[i]. It is givent that the seat desired by each person is between 11 and nn. The allotment is done in the following manner:

    • If the seat desired by the person in the front of the queue is empty, they are allotted that seat and removed from the queue.
    • If the seat desired by the person in the front of the queue is occupied, the seat number desired by them is incremented by 11 and they are pushed to the end of the queue.

    Find the final seat number allotted to each person in the queue. There are atmost 10510^5 people in the queue.

    Solution

    We will first store all the people who have not been alloted a seat in a stack to simulate their priority. We can also see that at max seats till index 2n2 \cdot n will be occupied. The rest can be seen from the implementation. The time complexity of the solution is O(n)O(n).

    1
    int main() {
    2
    int n;
    3
    cin >> n;
    4
    5
    vector<int> arr(n);
    6
    for (int i = 0; i < n; i++)
    7
    cin >> arr[i];
    8
    9
    vector<vector<int>> people(2 * n + 1);
    10
    for (int i = 0; i < n; i++)
    11
    people[arr[i]].push_back(i);
    12
    13
    vector<int> ans(n);
    14
    stack<int> st;
    15
    for (int seat = 1; seat <= 2 * n; seat++) {
    16
    if (!people[seat].empty()) {
    17
    // Allot seat to first person, and push rest to stack for later allotment
    18
    // in reverse order
    19
    auto p = people[seat];
    20
    ans[p[0]] = seat;
    21
    for (int i = p.size() - 1; i >= 0; i--)
    22
    st.push(p[i]);
    23
    } else {
    24
    if (!st.empty()) {
    25
    ans[st.top()] = seat;
    26
    st.pop();
    27
    }
    28
    }
    29
    }
    30
    31
    for (int i = 0; i < n; i++)
    32
    cout << ans[i] << " ";
    33
    }
  7. You are running a restaurant and are expecting nn customers. The customers are represented by a vector of N×3N \times 3 where the ithi^{th} customer is represented by (arrivali,departurei,numberDishesi)(arrival_i, departure_i, numberDishes_i). The ithi^{th} customer arrives at time arrivaliarrival_i and will stay till time departureideparture_i. The ithi^{th} customer will order numberDishesinumberDishes_i dishes. What is the minimum number of chefs you need to hire so that all the customers can be served?

    • Assume that any chef can prepare any dish in 11 unit of time.
    • A customer takes no time to eat the dishes after they are served, and they order all the dishes at once as soon as they come.
    Solution

    We will binary search on the number of chefs required. We can then simulate the process of serving the customers and check if the number of chefs required is less than or equal to the number of chefs we have. So simulate the process, we can use the greedy strategy of trying to serve the customer who is leaving the earliest first. Careful implementation is needed to ensure that you do not process the dishes of the customer before they arrive! I have used a priority queue to store the dishes to simulate the same. The time complexity of the solution is O(nlognlogA)O(n \log n \cdot \log A) where AA is the maximum number of chefs that can be needed.

    1
    using pq_type = priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>>;
    2
    3
    void processOrders(int curTime, int lastFreeTime, int chefCnt, pq_type &toProcess, vector<int> &served)
    4
    {
    5
    int canProcess = (curTime - lastFreeTime) * chefCnt;
    6
    while (!toProcess.empty() && canProcess)
    7
    {
    8
    auto p = toProcess.top();
    9
    toProcess.pop();
    10
    int leaveTime = p[0], quantity = p[1], idx = p[2];
    11
    12
    int process = min(canProcess, quantity);
    13
    canProcess -= process;
    14
    quantity -= process;
    15
    16
    if (quantity)
    17
    toProcess.push({leaveTime, quantity, idx});
    18
    else
    19
    served[idx] = 1;
    20
    }
    21
    }
    22
    23
    bool check(int chefCnt, vector<vector<int>> &customers)
    24
    {
    25
    int n = customers.size();
    26
    vector<int> served(n, 0);
    27
    28
    // pq -> stores [time, 0 / 1, idx]
    29
    // toProcess -> stores [leaveTime, quantity, idx]
    30
    pq_type pq, toProcess;
    31
    for (int i = 0; i < n; i++)
    32
    {
    33
    pq.push({customers[i][0], 0, i});
    34
    pq.push({customers[i][1], 1, i});
    35
    }
    36
    37
    int lastFreeTime = -1;
    38
    while (!pq.empty())
    39
    {
    40
    auto t = pq.top();
    41
    pq.pop();
    42
    int custIdx = t[2], type = t[1], curTime = t[0];
    43
    44
    if (type == 0)
    45
    {
    46
    toProcess.push({customers[custIdx][1], customers[custIdx][2], custIdx});
    47
    if (lastFreeTime == -1)
    48
    lastFreeTime = curTime;
    49
    processOrders(curTime, lastFreeTime, chefCnt, toProcess, served);
    50
    }
    51
    else
    52
    {
    53
    processOrders(curTime, lastFreeTime, chefCnt, toProcess, served);
    54
    if (!served[custIdx])
    55
    return 0;
    56
    }
    57
    lastFreeTime = curTime;
    58
    }
    59
    60
    return 1;
    61
    }
    62
    63
    int solve(vector<vector<int>> &customers)
    64
    {
    65
    int low = 1, high = 1e9, ans = -1;
    66
    while (low <= high)
    67
    {
    68
    int mid = (low + high) / 2;
    69
    if (check(mid, customers))
    70
    {
    71
    ans = mid;
    72
    high = mid - 1;
    73
    }
    74
    else
    75
    low = mid + 1;
    76
    }
    77
    78
    return ans;
    79
    }
  8. You are given a string ss whose length can be more than 10910^9. You are given an array arrarr and a string pp showing the count of the characters (for example, if arr=[1,2]arr = [1, 2] and pp is ab, then the string ss is abb). Count the number of sequences modulo 109+710^9 + 7 such that every subsequence contains all the vowels atleast once.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1arr[i]1051 \leq arr[i] \leq 10^5
    Solution

    We will make use of DP to solve this problem. We will maintain idxidx as the current index in the compressed string that we are processing, and a maskmask to represent the vowels that have occured atleast once in the current subsequence upto the index idxidx. The time complexity of the solution is O(n25logmax(arr[i]))O(n \cdot 2^5 \cdot \log max(arr[i])). The extra factor of logmax(arr[i])\log max(arr[i]) comes from the fact that we are using the binary exponentiation to calculate the powers of 22, which can be removed with the help of precomputation.

    1
    long long mod = 1e9 + 7;
    2
    3
    long long binPower(long long a, long long b)
    4
    {
    5
    long long res = 1;
    6
    while (b)
    7
    {
    8
    if (b & 1)
    9
    res = (res * a) % mod;
    10
    a = (a * a) % mod;
    11
    b >>= 1;
    12
    }
    13
    return res;
    14
    }
    15
    16
    int getVowelIdx(char c)
    17
    {
    18
    if (c == 'a')
    19
    return 0;
    20
    if (c == 'e')
    21
    return 1;
    22
    if (c == 'i')
    23
    return 2;
    24
    if (c == 'o')
    25
    return 3;
    26
    if (c == 'u')
    27
    return 4;
    28
    return -1;
    29
    }
    30
    31
    long long solve(int idx, int mask, string &p, vector<int> &arr, vector<vector<long long>> &dp)
    32
    {
    33
    if (idx == p.size())
    34
    return mask == 31;
    35
    36
    if (dp[idx][mask] != -1)
    37
    return dp[idx][mask];
    38
    39
    long long ans = 0;
    40
    int vowelIdx = getVowelIdx(p[idx]);
    41
    42
    if (vowelIdx == -1 || (mask & (1 << vowelIdx)))
    43
    {
    44
    // Not a vowel or already present, thus can take any number of occurences
    45
    // from 0 to arr[idx]
    46
    ans += solve(idx + 1, mask, p, arr, dp) * binPower(2, arr[idx]);
    47
    ans %= mod;
    48
    }
    49
    else
    50
    {
    51
    // Do not take the vowel
    52
    ans += solve(idx + 1, mask, p, arr, dp);
    53
    ans %= mod;
    54
    // Take atleast one occurence of the vowel
    55
    ans += solve(idx + 1, mask | (1 << vowelIdx), p, arr, dp) * (binPower(2, arr[idx] - 1));
    56
    ans %= mod;
    57
    }
    58
    59
    return dp[idx][mask] = ans;
    60
    }
    61
    62
    int countSubsequences(string p, vector<int> arr)
    63
    {
    64
    vector<vector<long long>> dp(p.size(), vector<long long>(32, -1));
    65
    return solve(0, 0, p, arr, dp);
    66
    }
  9. You are given three arrays aa, bb and cc of length nn each. In one operation, you can choose any one element from any one of the arrays and move it to any other array. After you have performed all the operations, we would sort each of the arrays indidually, and then concatenate them. What is the minimum number of operations that you must perform so that the final resulting array formed is also sorted?

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1a[i],b[i],c[i]1091 \leq a[i], b[i], c[i] \leq 10^9
    Solution

    We can use an approach similar to merging sorted arrays in this question. Let us first sort all the three arrays, and now try to form the new array. If we are able to add the element from the first array, then that is analogous to no operation being required for the sorting to be performed. On the other hand, it the current minimum is either from the second or the third array, then atleast one operation would be needed to put the same to it’s correct position. This can be simulated easily with the help of pointers or we can use priority queues for easier implementation. The time complexity of the solution is O(nlogn)O(n \log n).

    1
    int main()
    2
    {
    3
    int n;
    4
    cin >> n;
    5
    6
    vector<int> a(n), b(n), c(n);
    7
    8
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    9
    for (int i = 0; i < n; i++)
    10
    {
    11
    cin >> a[i];
    12
    pq.push({a[i], 0});
    13
    }
    14
    for (int i = 0; i < n; i++)
    15
    {
    16
    cin >> b[i];
    17
    pq.push({b[i], 1});
    18
    }
    19
    for (int i = 0; i < n; i++)
    20
    {
    21
    cin >> c[i];
    22
    pq.push({c[i], 2});
    23
    }
    24
    25
    int cntA = 0, cntB = 0, cntC = 0, ops = 0;
    26
    while (cntA + cntB + cntC != 3 * n)
    27
    {
    28
    auto [_, idx] = pq.top();
    29
    pq.pop();
    30
    31
    if (idx == 0)
    32
    cntA++;
    33
    else if (idx == 1)
    34
    {
    35
    cntB++;
    36
    if (cntA != n)
    37
    ops++;
    38
    }
    39
    else
    40
    {
    41
    cntC++;
    42
    if (cntA != n || cntB != n)
    43
    ops++;
    44
    }
    45
    }
    46
    47
    cout << ops << endl;
    48
    }
  10. You are given an array arrarr on length nn. In one operation you can choose any two distinct indexes ii and jj, remove both the elements from the array, and then add their sum back to the array at any position of your choice. What is the minimum number of operations required to make the array sorted in non-decreasing order?

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1arr[i]1091 \leq arr[i] \leq 10^9
    Solution

    Let us fix the elements that we would not change in the array, that is the longest non-decreasing subsequence in the array. We can then see that the elements that are not part of the longest non-decreasing subsequence must be removed and added back to the array. When adding back, we can always pair two elements together, and add them in the appropiate position in the sorted array. The time complexity of the solution is O(nlogn)O(n \log n).

    1
    int main() {
    2
    int n;
    3
    cin >> n;
    4
    5
    vector<int> arr(n);
    6
    for (int i = 0; i < n; i++)
    7
    cin >> arr[i];
    8
    9
    vector<int> lis;
    10
    for (int i = 0; i < n; i++) {
    11
    int idx = lower_bound(lis.begin(), lis.end(), arr[i] + 1) - lis.begin();
    12
    if (idx == lis.size())
    13
    lis.push_back(arr[i]);
    14
    else
    15
    lis[idx] = arr[i];
    16
    }
    17
    18
    cout << (n - lis.size() + 1)/2 << "\n";
    19
    }
  11. There are nn bacteria samples which are arranged in a row in a lab, from 11 to nn. There are mm number of pairs of bacteria, where a[i]a[i] bacteria is poisonous to the bacteria b[i]b[i]. Determine the number of intervals of samples that can coexist.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1m1051 \leq m \leq 10^5
    • 1a[i],b[i]n1 \leq a[i], b[i] \leq n
    Solution
    1
    int main() {
    2
    int n, m;
    3
    cin >> n >> m;
    4
    5
    vector<int> a(m), b(m);
    6
    for (int i = 0; i < m; i++)
    7
    cin >> a[i];
    8
    for (int i = 0; i < m; i++)
    9
    cin >> b[i];
    10
    11
    // Denotes the minimum index till which I can include
    12
    // in the subarray ending at me and still be safe
    13
    vector<int> d(n + 1, -1);
    14
    15
    for (int i = 0; i < m; i++) {
    16
    int u = a[i], v = b[i];
    17
    if (u > v)
    18
    swap(u, v);
    19
    d[v] = max(d[v], u);
    20
    }
    21
    22
    // All those in my range need to be safe too
    23
    for (int i = 1; i <= n; i++)
    24
    d[i] = max(d[i], d[i - 1]);
    25
    26
    long long ans = 0;
    27
    for (int i = 1; i <= n; i++) {
    28
    if (d[i] == -1)
    29
    ans += i;
    30
    else
    31
    ans += i - d[i];
    32
    }
    33
    34
    cout << ans << endl;
    35
    }
  12. Number of Ways

  13. For some array arrarr, the score of the array is defined as len(arr)max(arr)len(arr) * max(arr). Given an array arrarr, find the sum of the scores of all the non-empty subarrays of the array. Return the same modulo 109+710^9 + 7.

    Solution

    For each index ii, let us calculate the number of subarrays that have the maximum element as that index, and add the contribution of all those arrays to the answer. This can be done with the help of some maths and stacks. Remember to handle the equality of the elements in exactly one the computations of either the previous greater or the next greater and calculate the contribution of the lengths accordingly. The time complexity of the solution is O(n)O(n).

    1
    long long mod = 1e9 + 7;
    2
    3
    long long getCnt(long long x, long long y)
    4
    {
    5
    if (x > y)
    6
    swap(x, y);
    7
    8
    long long ans = x * (x + 1) / 2LL;
    9
    ans %= mod;
    10
    ans *= (x + y);
    11
    ans %= mod;
    12
    13
    long long ans2 = (y - x - 1) * x;
    14
    ans2 %= mod;
    15
    ans2 *= x;
    16
    ans2 %= mod;
    17
    18
    ans = (ans + ans2 + 2LL * mod) % mod;
    19
    return ans;
    20
    }
    21
    22
    int main()
    23
    {
    24
    int n;
    25
    cin >> n;
    26
    27
    vector<int> arr(n);
    28
    for (int i = 0; i < n; i++)
    29
    cin >> arr[i];
    30
    31
    stack<int> st;
    32
    vector<int> nxtGreater(n, n);
    33
    for (int i = 0; i < n; i++)
    34
    {
    35
    while (!st.empty() && arr[i] > arr[st.top()])
    36
    {
    37
    nxtGreater[st.top()] = i;
    38
    st.pop();
    39
    }
    40
    st.push(i);
    41
    }
    42
    while (!st.empty())
    43
    st.pop();
    44
    45
    vector<int> prevGreater(n, -1);
    46
    for (int i = n - 1; i >= 0; i--)
    47
    {
    48
    while (!st.empty() && arr[i] >= arr[st.top()])
    49
    {
    50
    prevGreater[st.top()] = i;
    51
    st.pop();
    52
    }
    53
    st.push(i);
    54
    }
    55
    56
    long long ans = 0;
    57
    for (int i = 0; i < n; i++)
    58
    {
    59
    arr[i] %= mod;
    60
    ans += getCnt(i - prevGreater[i], nxtGreater[i] - i) * arr[i];
    61
    ans %= mod;
    62
    }
    63
    64
    cout << ans << endl;
    65
    }

Online Assessment Questions

  1. Make Fence Great Again

    Solution

    The key realization to solve the problem is that you will never need to increment one number (or fence) by more than 22 times in the optimal solution. Using the same we can write a simple DP solution with the time complexity of O(n33)O(n \cdot 3 \cdot 3).

    1
    #include <bits/stdc++.h>
    2
    using namespace std;
    3
    4
    #define IOS \
    5
    ios_base::sync_with_stdio(0); \
    6
    cin.tie(0); \
    7
    cout.tie(0)
    8
    9
    #define ll long long int
    10
    #define vvll vector<vector<long long int>>
    11
    #define vpll vector<pair<long long int, long long int>>
    12
    #define range(x, s, n) for (int x = s; x < n; ++x)
    13
    14
    void solution();
    15
    16
    const int MOD = 1e9 + 7;
    17
    18
    int main()
    19
    {
    20
    IOS;
    21
    int TEST_CASES;
    22
    TEST_CASES = 1;
    23
    cin >> TEST_CASES;
    24
    while (TEST_CASES--)
    25
    solution();
    26
    return 0;
    27
    }
    28
    29
    ll solve(int idx, int lastIncr, vpll &arr, vvll &dp)
    30
    {
    31
    if (idx == arr.size())
    32
    return 0;
    33
    34
    if (dp[idx][lastIncr] != -1)
    35
    return dp[idx][lastIncr];
    36
    37
    ll cost = 1e18;
    38
    int lastEle = arr[idx - 1].first + lastIncr;
    39
    for (ll incr = 0; incr <= 2; incr++)
    40
    {
    41
    if (lastEle == arr[idx].first + incr)
    42
    continue;
    43
    cost = min(cost, incr * arr[idx].second + solve(idx + 1, incr, arr, dp));
    44
    }
    45
    return dp[idx][lastIncr] = cost;
    46
    }
    47
    48
    void solution()
    49
    {
    50
    int n;
    51
    cin >> n;
    52
    53
    vpll arr(n);
    54
    range(i, 0, n) cin >> arr[i].first >> arr[i].second;
    55
    56
    vvll dp(n, vll(3, -1));
    57
    ll ans = 1e18;
    58
    for (ll incr = 0; incr <= 2; incr++)
    59
    ans = min(ans, incr * arr[0].second + solve(1, incr, arr, dp));
    60
    61
    cout << ans << endl;
    62
    }
  2. You are given a tree with nn nodes, and each node has a value arr[i]arr[i]. You are given qq queries, and for each query you need to count the number of nodes with a prime value in the subtree of the query q[i]q[i]. The tree is rooted at 11.

    Constraints:

    • 1n,q1051 \leq n, q \leq 10^5
    • 1arr[i]1051 \leq arr[i] \leq 10^5
  3. You are given an even integer nn. You need to count the number of ways to colour a 1×n1 \times n grid using 33 colours such that no two adjacent cells have the same colour and the cells equidistant from the beginning and the end also do not have the same colour. Print the answer modulo 109+710^9 + 7.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • nn is even
  4. You are even a grid of size n×mn \times m. Each cell of the grid is either:

    1. 00 -> Meaning that it is free to move
    2. 11 -> Meaning that it is blocked
    3. 22 -> Meaning that it is a has a gold coin

    You need to begin at the point (0,0)(0,0) and end at the point (tx,ty)(t_x, t_y) and need to collect all the gold coins on the way. You can only move within the grid, and can move in any of the 44 directions. Find the minimum number of moves required to collect all the gold coins. You are allowed to visit multiple cells multiple times.

    Constraints:

    • 1n,m1001 \leq n, m \leq 100
    • Count of gold coins 10\leq 10
    • 0tx<n0 \leq t_x < n
    • 0ty<m0 \leq t_y < m

HiLabs Technologies

The company repeated the coding questions across campuses, even if the gap between the OA dates was more than 33 days. MCQs questions were also partially repeated across campuses, both for the SDE and DS roles.

Other Campus Questions

  1. You are given a graph with nn nodes and mm edges. The graph is undirected and unweighted. A bridge is an edge that, if removed, will increase the number of connected components in the graph. Find the number of pairs of nodes (u,v)(u, v) in the graph such that uvu \leq v and any path between uu and vv contains exactly one bridge.

    Constraints:

    • 1n,m1051 \leq n, m \leq 10^5
    Solution

    You can use Tarjan’s algorithm to find the bridges in the graph. Then, you can condense all the nodes in the graph that have no bridge between them into a single node. This technique is known as the bridge tree. Then the given condition converts to chosing two nodes in the bridge tree such that the path between them contains exactly one edge. The time complexity of the solution is O(n+m)O(n + m).

    1
    int main()
    2
    {
    3
    int n, m;
    4
    cin >> n >> m;
    5
    6
    vector<vector<int>> g(n);
    7
    for (int i = 0; i < m; i++)
    8
    {
    9
    int u, v;
    10
    cin >> u >> v;
    11
    u--, v--;
    12
    g[u].push_back(v);
    13
    g[v].push_back(u);
    14
    }
    15
    16
    vector<int> vis(n, 0), tin(n), low(n);
    17
    int timer = 0;
    18
    set<pair<int, int>> bridges;
    19
    20
    function<void(int, int)> dfs = [&](int u, int p) -> void
    21
    {
    22
    vis[u] = 1;
    23
    tin[u] = low[u] = timer++;
    24
    25
    for (int v : g[u])
    26
    {
    27
    if (v == p)
    28
    continue;
    29
    if (!vis[v])
    30
    {
    31
    dfs(v, u);
    32
    low[u] = min(low[u], low[v]);
    33
    if (low[v] > tin[u])
    34
    {
    35
    bridges.insert({u, v});
    36
    bridges.insert({v, u});
    37
    }
    38
    }
    39
    else
    40
    low[u] = min(low[u], low[v]);
    41
    }
    42
    };
    43
    dfs(0, -1);
    44
    45
    vector<int> compId(n, -1);
    46
    function<void(int, int, int)> bridgeDfs = [&](int u, int p, int comp) -> void
    47
    {
    48
    compId[u] = comp;
    49
    for (int v : g[u])
    50
    {
    51
    if (v == p || compId[v] != -1)
    52
    continue;
    53
    54
    if (bridges.find({u, v}) == bridges.end())
    55
    bridgeDfs(v, u, comp);
    56
    }
    57
    };
    58
    59
    int comp = 0;
    60
    for (int i = 0; i < n; i++)
    61
    if (compId[i] == -1)
    62
    bridgeDfs(i, -1, comp++);
    63
    64
    vector<int> compSize(comp + 1, 0);
    65
    for (int i = 0; i < n; i++)
    66
    compSize[compId[i]]++;
    67
    68
    long long ans = 0;
    69
    for (auto &[u, v] : bridges)
    70
    {
    71
    long long a = compId[u];
    72
    long long b = compId[v];
    73
    ans += compSize[a] * compSize[b];
    74
    }
    75
    76
    ans /= 2;
    77
    cout << ans << endl;
    78
    }
  2. You are given an array arrarr of length n1n - 1. What is the maximum GCD that you can obtain by selecting exactly n1n - 1 elements from the array?

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1arr[i]1091 \leq arr[i] \leq 10^9
    Solution

    We will try to exclude every element from the array and calculate the GCD of the remaining elements. The maximum GCD that we can obtain is the maximum of all the GCDs that we calculate. This calculation can be done in O(n)O(n) time by using prefix and suffix GCD arrays. The time complexity of the solution is O(nlogAmax)O(n \log A_{max}).

    1
    int main()
    2
    {
    3
    int n;
    4
    cin >> n;
    5
    6
    vector<int> arr(n);
    7
    for (int i = 0; i < n - 1; i++)
    8
    cin >> arr[i];
    9
    10
    vector<int> prefix(n), suffix(n);
    11
    prefix[0] = arr[0];
    12
    for (int i = 1; i < n - 1; i++)
    13
    prefix[i] = __gcd(prefix[i - 1], arr[i]);
    14
    15
    suffix[n - 1] = arr[n - 1];
    16
    for (int i = n - 2; i >= 0; i--)
    17
    suffix[i] = __gcd(suffix[i + 1], arr[i]);
    18
    19
    int ans = 0;
    20
    for (int i = 0; i < n; i++)
    21
    {
    22
    int curGCD = i == 0 ? suffix[1] : (i == n - 1 ? prefix[n - 2] : __gcd(prefix[i - 1], suffix[i + 1]));
    23
    ans = max(ans, curGCD);
    24
    }
    25
    26
    cout << ans << endl;
    27
    }
  3. A compnay has nn servers, labelled from 11 to nn, all of which initally have no workload. mm requests are sent to the company’s API, where the requests are distributed evenly between the servers. An even distribution ensures that the busiest server has the least possible load. Print which server would handle the request for each API request.

    • 1n1051 \leq n \leq 10^5
    • 1m1051 \leq m \leq 10^5
    • 1requests[i]1091 \leq requests[i] \leq 10^9
    Solution

    Use a priority queue to store the servers and their loads. The time complexity of the solution is O(mlogn)O(m \log n).

    1
    int main()
    2
    {
    3
    int n, m;
    4
    cin >> n >> m;
    5
    6
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    7
    for (int i = 1; i <= n; i++)
    8
    pq.push({0, i});
    9
    10
    for (int i = 0; i < m; i++)
    11
    {
    12
    cin >> load;
    13
    auto [curLoad, server] = pq.top();
    14
    pq.pop();
    15
    cout << server << " ";
    16
    pq.push({curLoad + load, server});
    17
    }
    18
    }
  4. You are given an array arrarr of length nn. You need to find the number of ways to divide the array into subarrays such that each subarray has exactly one 11 present in it. The length of the array is up to 10610^6. The answer can be large, so print the answer modulo 109+710^9 + 7.

    Solution

    We can simply store the indices of all the 11s in the array and then perform a cut at each of the position between two consecutive 11s. The time complexity of the solution is O(n)O(n).

    1
    int solve(vector<int> arr) {
    2
    int n = arr.size();
    3
    4
    vector<int> oneIdx;
    5
    for (int i = 0; i < n; i++) {
    6
    if (arr[i] == 1) {
    7
    oneIdx.push_back(i);
    8
    }
    9
    }
    10
    11
    if (oneIdx.size() <= 1) return oneIdx.size();
    12
    13
    long long ways = 1, MOD = 1e9 + 7;
    14
    for (int i = 1; i < oneIdx.size(); i++) {
    15
    ways = (ways * (oneIdx[i] - oneIdx[i - 1])) % MOD;
    16
    }
    17
    18
    return ways;
    19
    }
  5. A consisent sequence is a binary string where all the adjacent elements are different. You are given an integer nn. Find the number of consistent subsequences of a consistent sequence of length nn starting with the character 00. Return the number of subsequences modulo 109+710^9 + 7.

    • 1n1051 \leq n \leq 10^5
    Solution

    The sequence given to us is nothing but 010101010101\ldots and we need to find the alternating sequence of 00s and 11s. We can use a simple DP to solve this problem. The time complexity of the solution is O(n)O(n).

    long long MOD = 1e9 + 7;
    long long solve(int idx, int need, int n, vector<vector<long long>> &dp)
    {
    if (idx == n)
    return 1;
    if (dp[idx][need] != -1)
    return dp[idx][need];
    dp[idx][need] = solve(idx + 1, need, n, dp);
    if (idx % 2 == need)
    {
    dp[idx][need] += solve(idx + 1, !need, n, dp);
    dp[idx][need] %= MOD;
    }
    return dp[idx][need];
    }
    int consistentSubsequence(int n)
    {
    vector<vector<long long>> dp(n, vector<long long>(2, -1));
    // -1 to remove empty subsequence
    long long ans = solve(0, 0, n, dp) - 1;
    ans += solve(0, 1, n, dp) - 1;
    ans = (ans + 2 * MOD) % MOD;
    return ans;
    }
  6. The beauty of an subarray between (i,j)(i, j) of array arrarr is defined as k=ik=j(arr[k])+c(ji)\sum_{k = i}^{k = j} (arr[k]) + c \cdot (j - i). Print the maximum value of the beauty across all the possible distinct indexes (u,v)(u, v) in the array.

    Solution

    We maintain the largest value of beauty in the subarray. Then at any index either we can start a new subarray or extend the current subarray by adding the element and one unit of cc. The time complexity of the solution is O(n)O(n).

    long long maximumQuirkness(vector<int> &arr, long long cost)
    {
    long long sufMax = arr.back();
    long long ans = -1e18;
    for (int i = arr.size() - 2; i >= 0; i--)
    {
    ans = max(ans, sufMax + arr[i] + cost);
    sufMax = max(arr[i] + cost + sufMax, (long long)arr[i]);
    }
    return ans;
    }
  7. The beauty of an subarray between (i,j)(i, j) of array arrarr is defined as k=ik=j(arr[k]+c(ji))+2ij\sum_{k = i}^{k = j} (arr[k] + c \cdot (j - i)) + 2 \cdot i \cdot j. Print the maximum value of the beauty across all the possible distinct indexes (u,v)(u, v) in the array. The array is 11 indexed.

  8. You have nn coins with values from 00 to n1n - 1. Find the number of ways of choosing exactly kk coins such that the sum of the coins is divisible by mm. Return the number of ways modulo 1e9+71e9 + 7.

    Constraints:

    • 1n1031 \leq n \leq 10^3
    • 1kmin(n,102)1 \leq k \leq min(n, 10^2)
    • 1m1031 \leq m \leq 10^3
    Solution

    We can use a take or not-take approach to solve this problem. The state of the DP can be represented as (i,j,k)(i, j, k) where ii is the coin that we are considering right now, jj is the number of coins taken that we can take in the next moves, and kk is the sum of the coins that must be taken in the next moves modulo mm. The time complexity of the solution is O(nkm)O(n \cdot k \cdot m) as each state can be reached in O(1)O(1) time.

    int main()
    {
    int n, k, m;
    cin >> n >> k >> m;
    using ll = long long;
    using vll = vector<ll>;
    vector<vector<vll>> dp(n + 1, vector<vll>(k + 1, vll(m + 1, 0)));
    dp[n][0][0] = 1;
    ll MOD = 1e9 + 7;
    for (int i = n - 1; i >= 0; i--)
    for (int j = 0; j <= k; j++)
    for (int l = 0; l <= m; l++)
    {
    dp[i][j][l] = dp[i + 1][j][l];
    if (j > 0)
    {
    int reqMod = l - i;
    reqMod = ((reqMod % m) + m) % m;
    dp[i][j][l] += dp[i + 1][j - 1][reqMod];
    }
    dp[i][j][l] %= MOD;
    }
    cout << dp[0][k][0] << endl;
    }

    This might give TLE in a 11 time limit or MLE in strict constraints, so we can space optimise the same and make use of arrays instead of vectors to improve the performance.

    Space Optimised Solution
    1
    const int MAXK = 100, MAXM = 1000;
    2
    long long cur[MAXK + 1][MAXM + 1], nxt[MAXK + 1][MAXM + 1];
    3
    4
    int main()
    5
    {
    6
    int n, k, m;
    7
    cin >> n >> k >> m;
    8
    9
    memset(nxt, 0, sizeof(nxt));
    10
    nxt[0][0] = 1;
    11
    12
    long long MOD = 1e9 + 7;
    13
    14
    for (int i = n - 1; i >= 0; i--)
    15
    {
    16
    memset(cur, 0, sizeof(cur));
    17
    18
    for (int j = 0; j <= k; j++)
    19
    for (int l = 0; l <= m; l++)
    20
    {
    21
    cur[j][l] = nxt[j][l];
    22
    if (j > 0)
    23
    {
    24
    int reqMod = l - i;
    25
    reqMod = ((reqMod % m) + m) % m;
    26
    cur[j][l] += nxt[j - 1][reqMod];
    27
    }
    28
    cur[j][l] %= MOD;
    29
    }
    30
    31
    memcpy(nxt, cur, sizeof(cur));
    32
    }
    33
    34
    cout << nxt[k][0] << endl;
    35
    }
  9. You are standing at position kk. You can move to any position which is the product of any two elements of the array arrarr from the current position. Find the maximum distance you can move in one jump.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 109arr[i]109-10^9 \leq arr[i] \leq 10^9
    • 109k109-10^9 \leq k \leq 10^9
    Solution

    You will make the jump to either the most positive position possible or the most negative position possible. The time complexity of the solution is O(nlogn)O(n \log n) due to the sorting.

    1
    int main()
    2
    {
    3
    long long n, k;
    4
    cin >> n >> k;
    5
    6
    vector<long long> arr(n);
    7
    for (int i = 0; i < n; i++)
    8
    cin >> arr[i];
    9
    10
    sort(arr.begin(), arr.end());
    11
    12
    long long maxPos1 = arr[n - 1] * arr[n - 2];
    13
    long long maxPos2 = arr[0] * arr[1];
    14
    long long maxPos3 = arr[0] * arr[n - 1];
    15
    16
    long long d = max({abs(maxPos1 - k),
    17
    abs(maxPos2 - k),
    18
    abs(maxPos3 - k)});
    19
    20
    cout << d << endl;
    21
    }
  10. You are given an array of distinct elements arr[i]arr[i]. You elements aa and bb can be connected by an edge if lcm(a,b)106lcm(a, b) \leq 10^6. Find the minimum number of connected components possible in from the given array.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1arr[i]1091 \leq arr[i] \leq 10^9
    Solution

    It is obvious that elements greater than 10910^9 when paired with any other element would have a lcmlcm greater than 10610^6. So we can ignore all the elements greater than 10610^6. Now let us fix the gcdgcd as gg. We can push all the elements that are divisible by gg into an array. Now it is certain that all the elements in this array with have a gcdgcd of atleadt gg. We can use a two pointer approach to connect all the elements in the array that have ab106ga * b \leq 10^6 \cdot g. We will use a DSU to connect all the elements in the array. The time complexity of the solution is O(n+AlogA)O(n + A \log A) where AA is 10610^6.

    1
    class DSU
    2
    {
    3
    public:
    4
    vector<int> parent, size;
    5
    6
    DSU(int n)
    7
    {
    8
    parent.resize(n);
    9
    size.resize(n, 1);
    10
    for (int i = 0; i < n; i++)
    11
    parent[i] = i;
    12
    }
    13
    14
    int find(int x)
    15
    {
    16
    if (parent[x] == x)
    17
    return x;
    18
    return parent[x] = find(parent[x]);
    19
    }
    20
    21
    void unite(int x, int y)
    22
    {
    23
    x = find(x);
    24
    y = find(y);
    25
    if (x != y)
    26
    {
    27
    if (size[x] < size[y])
    28
    swap(x, y);
    29
    parent[y] = x;
    30
    size[x] += size[y];
    31
    }
    32
    }
    33
    };
    34
    35
    int solve(vector<int> &arr)
    36
    {
    37
    int n = arr.size();
    38
    39
    const int LIMIT = 1e6;
    40
    DSU dsu(LIMIT + 1);
    41
    42
    int compCnt = 0;
    43
    vector<int> pre(LIMIT + 1, 0);
    44
    for (int i = 0; i < n; i++)
    45
    {
    46
    if (arr[i] > LIMIT)
    47
    compCnt++;
    48
    else
    49
    pre[arr[i]] = 1;
    50
    }
    51
    52
    for (int gcd = 1; gcd <= LIMIT; gcd++)
    53
    {
    54
    vector<long long> ele;
    55
    for (int j = gcd; j <= LIMIT; j += gcd)
    56
    if (pre[j])
    57
    ele.push_back(j);
    58
    59
    long long maxProduct = (long long)1e6 * gcd;
    60
    int n = ele.size();
    61
    62
    int j = 0;
    63
    for (int i = 0; i < n; i++)
    64
    {
    65
    if (j < i)
    66
    j = i;
    67
    dsu.unite(ele[i], ele[j]);
    68
    while (j + 1 < n && ele[i] * ele[j + 1] <= maxProduct)
    69
    {
    70
    dsu.unite(ele[i], ele[j + 1]);
    71
    j++;
    72
    }
    73
    }
    74
    }
    75
    76
    set<int> par;
    77
    for (int x : arr)
    78
    if (x <= LIMIT)
    79
    par.insert(dsu.find(x));
    80
    81
    return par.size() + compCnt;
    82
    }
  11. Candle Problem

  12. You are given a tree with nn nodes with one node intially marked as black, and the rest marked as white. In one operation, you can colour any of the nodes black only if atleast one the neighbours of the node is black. Count the possible number of colourings of the tree. Return the answer modulo 109+710^9 + 7.

    Solution

    We can use simple DFS to solve this problem. Let the dfsdfs function return the number of ways of colouring the subtree of uu (when the whole tree is rooted at rootroot) and the node uu is coloured black. Then for every child node, we can either leave it white, resulting in 11 way of colouring, or colour it black which can be calculated recursively by multiplying with the result of the dfsdfs function. All the ways for all the children are multiplied together to get the final result. The complexity of the solution is O(n)O(n).

    1
    long long mod = 1e9 + 7;
    2
    3
    long long dfs(int u, int p, vector<vector<int>> &g)
    4
    {
    5
    long long ans = 1;
    6
    for (int v : g[u])
    7
    {
    8
    if (v == p)
    9
    continue;
    10
    ans *= (1 + dfs(v, u, g));
    11
    ans %= mod;
    12
    }
    13
    return ans;
    14
    }
    15
    16
    int main()
    17
    {
    18
    int n;
    19
    cin >> n;
    20
    21
    vector<vector<int>> g(n);
    22
    for (int i = 0; i < n - 1; i++)
    23
    {
    24
    int u, v;
    25
    cin >> u >> v;
    26
    u--, v--;
    27
    g[u].push_back(v);
    28
    g[v].push_back(u);
    29
    }
    30
    31
    int root;
    32
    cin >> root;
    33
    root--;
    34
    35
    cout << dfs(root, -1, g) << endl;
    36
    37
    }
  13. When comparing two numbers, you need to first compare the sum of digits of the two numbers, and only if they are the same, then you need to compare the actual values of the numbers themselves. Given an array arrarr, for each index, find the index of the closest number to the right that is bigger than the number at the given index according to the comparision scheme specified above. If no such number exists, print 1-1.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1arr[i]1091 \leq arr[i] \leq 10^9
  14. You are given array AA of size NN. You can make atmost KK operations on the same, where in each operation you can increase or decrease an element in array by 11. Now, the beauty of array is frequency of most frequent element in the array. Output the maximum beauty that can be achieved in KK operations.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1k10181 \leq k \leq 10^{18}
    • 109arr[i]109-10^9 \leq arr[i] \leq 10^9
    Solution

    Let us first sort the array and try to binary search on the answer. It is clear that when we are checking the validity for an answer xx, we would want some subarray of the sorted array to become all equal to xx. Thus we can maintain a sliding window, and calculate the required number of operations for each window. It is a well known fact that given a sorted array, the median of the array is the point from where the number of operations required to make the array all equal by increments and decrements is minimum. We can use prefix sums to calculate the number of operations required to make the array all equal to xx in O(1)O(1) time for any subarray. Thus the overall complexity of the solution is O(nlogn)O(n \log n).

    1
    int main()
    2
    {
    3
    int n;
    4
    long long k;
    5
    cin >> n >> k;
    6
    7
    vector<int> arr(n);
    8
    for (int i = 0; i < n; i++)
    9
    cin >> arr[i];
    10
    sort(arr.begin(), arr.end());
    11
    12
    vector<long long> pre(n);
    13
    pre[0] = arr[0];
    14
    for (int i = 1; i < n; i++)
    15
    pre[i] = pre[i - 1] + arr[i];
    16
    17
    auto getRangeSum = [&](int l, int r) -> long long
    18
    {
    19
    if (l > r)
    20
    return 0;
    21
    return pre[r] - (l == 0 ? 0 : pre[l - 1]);
    22
    };
    23
    24
    auto getMinOpsAtIdx = [&](int l, int r, int m) -> long long
    25
    {
    26
    long long sum1 = getRangeSum(l, m - 1);
    27
    sum1 = (long long)(m - l) * arr[m] - sum1;
    28
    29
    long long sum2 = getRangeSum(m, r);
    30
    sum2 = sum2 - (long long)(r - m + 1) * arr[m];
    31
    32
    return sum1 + sum2;
    33
    };
    34
    35
    auto getMinOps = [&](int l, int r) -> long long
    36
    {
    37
    int len = r - l + 1;
    38
    if (len % 2 == 1)
    39
    return getMinOpsAtIdx(l, r, l + len / 2);
    40
    else
    41
    {
    42
    long long m1 = l + len / 2 - 1, m2 = l + len / 2;
    43
    return min(getMinOpsAtIdx(l, r, m1), getMinOpsAtIdx(l, r, m2));
    44
    }
    45
    };
    46
    47
    auto checkLength = [&](int l) -> bool
    48
    {
    49
    for (int i = 0; i <= n - l; i++)
    50
    if (getMinOps(i, i + l - 1) <= k)
    51
    return true;
    52
    return false;
    53
    };
    54
    55
    int ans = 0;
    56
    int l = 1, r = n;
    57
    58
    while (l <= r)
    59
    {
    60
    int m = (l + r) / 2;
    61
    if (checkLength(m))
    62
    {
    63
    ans = m;
    64
    l = m + 1;
    65
    }
    66
    else
    67
    r = m - 1;
    68
    }
    69
    70
    cout << ans << endl;
    71
    }
  15. You are given a tree with nn nodes and each node has the value 00 initially. The tree is rooted at 11. You need to perform qq queries on the same of the following types:

    • 1 X Y: Increase the value of all the nodes in the subtree of node XX by YY.
    • 2 X Y: Increase the value of all nodes by YY except the nodes in the subtree of node XX.

    Print the final values of all the nodes in the tree.

    Constraints:

    • 1n,q1051 \leq n, q \leq 10^5
    • 1Xn1 \leq X \leq n
    • 109Y109-10^9 \leq Y \leq 10^9
    Solution
    1
    int main()
    2
    {
    3
    int n;
    4
    cin >> n;
    5
    6
    vector<vector<int>> g(n);
    7
    for (int i = 0; i < n - 1; i++)
    8
    {
    9
    int u, v;
    10
    cin >> u >> v;
    11
    u--, v--;
    12
    g[u].push_back(v);
    13
    g[v].push_back(u);
    14
    }
    15
    16
    int timer = 0;
    17
    vector<int> tin(n), tout(n);
    18
    19
    function<void(int, int)> dfs = [&](int u, int p) -> void
    20
    {
    21
    tin[u] = timer++;
    22
    for (int v : g[u])
    23
    {
    24
    if (v == p)
    25
    continue;
    26
    dfs(v, u);
    27
    }
    28
    tout[u] = timer++;
    29
    };
    30
    dfs(0, -1);
    31
    32
    vector<long long> dif(2 * n + 1);
    33
    34
    int q;
    35
    cin >> q;
    36
    while (q--)
    37
    {
    38
    int ty, x, y;
    39
    cin >> ty >> x >> y;
    40
    x--;
    41
    42
    if (ty == 1)
    43
    {
    44
    dif[tin[x]] += y;
    45
    dif[tout[x] + 1] -= y;
    46
    }
    47
    else
    48
    {
    49
    dif[tin[0]] += y;
    50
    dif[tout[0] + 1] -= y;
    51
    52
    dif[tin[x]] -= y;
    53
    dif[tout[x] + 1] += y;
    54
    }
    55
    }
    56
    57
    for (int i = 1; i <= 2 * n; i++)
    58
    dif[i] += dif[i - 1];
    59
    60
    for (int i = 0; i < n; i++)
    61
    cout << dif[tin[i]] << " ";
    62
    }
  16. This question was asked in the Software Developer role, and a workspace was provided to work on the same. You are required to design a simple HTML page that accepts from the user the number of rows and columns, and then makes a table of the specified dimensions. There is bonus marking for CSS styling.

    HTML Code
    <!doctype html>
    <html>
    <head>
    <title>Test</title>
    <style>
    body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 5px;
    }
    input {
    margin-left: 5px;
    margin-right: 5px;
    }
    table {
    text-align: center;
    }
    tr:nth-child(even) {
    background-color: lightgrey;
    }
    tr:hover {
    background-color: lightcyan;
    }
    td {
    border: 1px solid black;
    margin: 0;
    padding: 1px;
    }
    </style>
    </head>
    <body>
    <center>
    <form name="input-form">
    <label for="rows" tabindex="1">Rows</label>
    <input
    type="number"
    name="rows"
    required
    min="1"
    max="10"
    id="rows"
    />
    <label for="cols" tabindex="2">Columns</label>
    <input
    type="number"
    name="cols"
    required
    min="1"
    max="10"
    id="cols"
    />
    <button type="submit" tabindex="3">Submit</button>
    <button type="reset" tabindex="4">Reset</button>
    </form>
    <h2>Generated Table</h2>
    <table id="main-table"></table>
    </center>
    </body>
    <script>
    const tableDiv = document.getElementById("main-table");
    const form = document.forms["input-form"];
    const resetValues = () => {
    form["rows"].value = "";
    form["cols"].value = "";
    };
    const handleSubmit = (event) => {
    event.preventDefault();
    const rows = +form["rows"].value,
    cols = +form["cols"].value;
    if (Number.isNaN(rows) || Number.isNaN(cols)) {
    alert("Please enter valid value of rows and columns");
    resetValues();
    return;
    }
    if (rows == 0 || cols == 0) {
    alert("Rows and columns can't be zero");
    resetValues();
    return;
    }
    plotTable(rows, cols);
    };
    const plotTable = (rows, cols) => {
    tableDiv.innerHTML = "";
    for (let r = 0; r < rows; r++) {
    const rowEle = document.createElement("tr");
    for (let c = 0; c < cols; c++) {
    const colEle = document.createElement("td");
    colEle.innerHTML = `Row ${r + 1} Col ${c + 1}`;
    rowEle.appendChild(colEle);
    }
    tableDiv.appendChild(rowEle);
    }
    };
    form.addEventListener("submit", handleSubmit);
    </script>
    </html>

Online Assessment Questions

  1. You are given a string ss and a dictionary of words as arrarr of length nn. You need to find the word from the dictionary with the minimum edit distance with respect to the provided string ss. If there are multiple such words, return the lexographically smallest word.

    Constraints:

    • 1n1041 \leq n \leq 10^4
    • 1s101 \leq |s| \leq 10
    • 1arr[i]101 \leq |arr[i]| \leq 10
  2. You are given a string ss of length nn denoting a valid binary expression. The string can have the following characters:

    • x: Denotes the primary variable
    • X: Denotes the negation of the primary variable
    • 1: Denotes the logical true value
    • 0: Denotes the logical false value
    • &: Denotes the logical and operation
    • |: Denotes the logical or operation
    • ^: Denotes the logical xor operation
    • (: Denotes the start of a subexpression
    • ): Denotes the end of a subexpression

    You need to determine the minimum number of substituitons required (replace any x or X with 0 or 1) to make the expression evaluate to either true or false. There are multiple testcases, and you need to print the result for each testcase in a new line.

    Constraints:

    • 1t101 \leq t \leq 10
    • 1n1051 \leq n \leq 10^5
    • The expression is always valid.

    Sample Input:

    5
    1&0
    x
    1|(x^x&(x|0))
    1|0
    (0|x|(X^1^x^X))

    Sample Output & Explanation:

    0 -> The expression is already false
    1 -> The expression can be made true or false by replacing x with 1 or 0
    0 -> The expression is already true, irrespective of the value of x
    0 -> The expression is already false
    1 -> We can set x = 1 to make the expression true
  3. A UI screenshot involving three buttons and a picture was given. Depending upon which button is clicked, the image shown shown be changed. Some amount of Flexbox and CSS was required to position the buttons and the image in the correct manner as shown in the UI. Asthetics was also a part of the marking.


InMobi

Other Campus Questions

  1. You are given nn projects, where the ithi^{th} project has a pure profit of profit[i]profit[i] and a minimum capital of capital[i]capital[i] is required to start the same. Initially you have ww capital. Whenever you complete a project, you will obtain its pure profit and the same would be added to your capital. Pick a list of at most kk distinct projects from the given projects to maximise your final capital, and return the final maximised capital.

    This question is repeat of IPO on Leetcode.

  2. Wiggle Subsequence

    Solution
    int wiggleMaxLength(vector<int>& nums) {
    int size = nums.size(), peak = 1, valley = 1;
    for (int i = 1; i < size; ++i) {
    if (nums[i] > nums[i-1])
    peak = valley + 1;
    else if (nums[i] < nums[i-1])
    valley = peak + 1;
    }
    return max(peak , valley);
    }
  3. You are given a string wordword of lowercase English letters. You need to select one index from it and remove the letter at that index from wordword such that the frequency of every letter in wordword is equal. Return true if it possible to do so in exactly one operation, or else return false.

  4. X of a Kind in a Deck of Cards

  5. Fruits into Baskets

  6. Longest Valid Parentheses

  7. Remove Letter to Equlaize Frequency

  8. Imagine a vertical line cutting through the root node, thus dividing the left and right sub-trees of it. A mirror element of a node xx satisfies the following three properties:

    • It is on the opposite side of the dividing line.
    • It is at the same depth as xx.
    • It’s horizontal distance from the vertical dividing line is the same as that of xx.

    Your task is to write a program logic that first creates a Binary Search Tree, then creates a mirrored tree out of it, and finally prints the preorder (Root, Left, Right) traversal of the mirrored tree. Your program will be provided with the number of nodes in the Binary Search Tree and the data of nodes separated by space in the next line.

    Solution

    This question can be seen as a conjuction of three standard DSA problems:

    1. Creating a balanced BST from a sorted array.
    2. Mirroring a binary tree.
    3. Preorder traversal of a binary tree.

    The implementation is relatively simple. The time complexity of the solution is O(n)O(n).

    class Node
    {
    public:
    Node *left, *right;
    int val;
    Node() : left(nullptr), right(nullptr), val(-1) {}
    Node(int x) : left(nullptr), right(nullptr), val(x) {}
    };
    Node *build(int l, int r, vector<int> &arr)
    {
    if (l > r)
    return nullptr;
    if (l == r)
    return new Node(arr[l]);
    int m = (l + r) / 2;
    Node *n = new Node(arr[m]);
    n->left = build(l, m - 1, arr);
    n->right = build(m + 1, r, arr);
    return n;
    }
    void flip(Node *root)
    {
    if (root == nullptr)
    return;
    swap(root->left, root->right);
    flip(root->left);
    flip(root->right);
    }
    void print(Node *root)
    {
    if (root == nullptr)
    return;
    cout << root->val << " ";
    print(root->left);
    print(root->right);
    }
    int main()
    {
    int n;
    cin >> n;
    vector<int> arr(n);
    for (int i = 0; i < n; i++)
    cin >> arr[i];
    Node *root = build(0, n - 1, arr);
    flip(root);
    print(root);
    }
  9. Aggressive Cows

  10. Word Ladder

  11. Trapping Rain Water

  12. Try all the variants of the House Robber problem.

  13. Buy & Sell Stocks atmost K Times

  14. Cycle Detection in Directed Graph

Online Assessment Questions

  1. Given an array of size NN, find the missing and duplicate integer in the array. The array is supposed to all the integers between 11 and NN exactly once.

  2. Find the probability to reach the target node from the root node 11 in an unweighted undirected tree in time tt. In each second you can visit one of the unvisited nodes from the current node with equal probability, and if there are no unvisited nodes, you can stay at the same node. The tree is given in the form of an adjacency list.

  3. Given an integer kk and character arrarr of size nn containing two characters: GG for guard and II for intruder, you need to count the maximum number of intruders that can be caught. A guard can catch only one thief if it lies in range [ik,i+k][i-k, i+k] where ii is the position of the guard under consideration.


Dream 11

Other Campus Questions

  1. Cricket is a team sport comprised of 1111 player each team has four types of player: Batsman, Bowler, All-Rounder, and Wicket Keeper. Dream11 is a fantasy cricket platform where users create their own cricket teams. You have decided to participate in Dream11 during the IPL season. The platform rewards prizes based on the maximum total value of your team. Your task is to create a cricket team based on certain constraints to win the reward.

    Write a program to do so while adhering to the following constraints:

    1. Your team must consist of 1111 players.
    2. You have a budget of BB to spend on selecting players.
    3. Each player has a price tag and a player value.
    4. There are four types of player: Batsman, Bowler, All-Rounder, and Wicket Keeper.
    5. Your team should have at least one Wicket Keeper, one All-Rounder, two Batsmen, two Bowlers.
    6. Now given list of price and player values to determine the type of players:
      • The first 20% of players are considered as Wicket Keepers. Note: Take the ceil of the number obtained.
      • Batsmen are selected from odd positions (excluding the first 20%).
      • Bowlers are selected from the even positions that are not divisible by 4 (excluding the first 20%).
      • All-Rounders are selected from positions divisible by 4 (excluding the first 20%).
      • Player index starts from zero. Please factor this in calculation of player types viz. Wicket Keeper, All-Rounder, Batsmen and Bowler.

    Print the maximum total value MM which is the summation of the selected player values, that can be obtained while satisfying all the constraints and is within the budget else print Insufficient Budget.

    Constraints

    • 11N20011 \leq N \leq 200
    • 1B10001 \leq B \leq 1000
    • 1P201 \leq P \leq 20
    • 1V201 \leq V \leq 20
    Example #1
    12
    4 3 3 6 5 2 8 8 2 7 8 2
    2 1 1 2 3 6 1 6 2 7 6 3
    50
    Output #1: 34
    Example #2
    12
    4 3 3 6 5 2 8 8 2 7 9 2
    2 1 1 2 3 6 1 6 2 7 6 3
    50
    Output #2: Insufficient Budget
    Solution

    We will use dynamic programming to solve this problem. We will maintain a 66-dimensional DP array where the dimensions are the index of the player, the budget left, the number of Wicket Keepers, the number of All Rounders, the number of Bowlers, the number of Batsmen, and the total number of players. We would also need to space optimise the solution as the number of dimensions is too high. The time complexity of the solution is O(nB223312)O(n \cdot B \cdot 2 \cdot 2 \cdot 3 \cdot 3 \cdot 12 ) which approximately equals 10810^8 operations.

    1
    // 0 -> WK, 1 -> Bat, 2 -> Bowl, 3 -> All Rounder
    2
    int getType(int i, int n)
    3
    {
    4
    int wkCnt = ceil((double)n * 0.2);
    5
    if (i < wkCnt)
    6
    return 0;
    7
    8
    if (i % 2 == 1)
    9
    return 1;
    10
    11
    if (i % 4 == 0)
    12
    return 3;
    13
    14
    return 2;
    15
    }
    16
    17
    int main()
    18
    {
    19
    int n;
    20
    cin >> n;
    21
    22
    vector<int> cost(n), val(n);
    23
    for (int i = 0; i < n; i++)
    24
    cin >> cost[i];
    25
    for (int i = 0; i < n; i++)
    26
    cin >> val[i];
    27
    28
    int b;
    29
    cin >> b;
    30
    31
    // idx, budget left, wk, all rounder, bowl, bat, total
    32
    int cur[b + 1][2][2][3][3][12], nxt[b + 1][2][2][3][3][12];
    33
    memset(cur, -1, sizeof(cur));
    34
    memset(nxt, -1, sizeof(nxt));
    35
    36
    cur[b][0][0][0][0][0] = 0;
    37
    38
    for (int idx = 0; idx < n; idx++)
    39
    {
    40
    for (int budLeft = 0; budLeft <= b; budLeft++)
    41
    for (int wk = 0; wk < 2; wk++)
    42
    for (int ar = 0; ar < 2; ar++)
    43
    for (int bowl = 0; bowl < 3; bowl++)
    44
    for (int bat = 0; bat < 3; bat++)
    45
    for (int tot = 0; tot < 12; tot++)
    46
    {
    47
    if (cur[budLeft][wk][ar][bowl][bat][tot] == -1)
    48
    continue;
    49
    50
    // Do not take the player
    51
    nxt[budLeft][wk][ar][bowl][bat][tot] = max(
    52
    nxt[budLeft][wk][ar][bowl][bat][tot],
    53
    cur[budLeft][wk][ar][bowl][bat][tot]);
    54
    55
    // Buy the player
    56
    if (tot < 11 && budLeft >= cost[idx])
    57
    {
    58
    int ty = getType(idx, n);
    59
    int newBud = budLeft - cost[idx];
    60
    int newWk = wk | (ty == 0);
    61
    int newBat = min(bat + (ty == 1), 2);
    62
    int newBowl = min(bowl + (ty == 2), 2);
    63
    int newAr = ar | (ty == 3);
    64
    65
    nxt[newBud][newWk][newAr][newBowl][newBat][tot + 1] = max(
    66
    nxt[newBud][newWk][newAr][newBowl][newBat][tot + 1],
    67
    cur[budLeft][wk][ar][bowl][bat][tot] + val[idx]);
    68
    }
    69
    }
    70
    71
    memcpy(cur, nxt, sizeof(nxt));
    72
    memset(nxt, -1, sizeof(nxt));
    73
    }
    74
    75
    int ans = -1;
    76
    for (int left = 0; left <= b; left++)
    77
    ans = max(ans, cur[left][1][1][2][2][11]);
    78
    79
    if (ans == -1)
    80
    cout << "Insufficient Budget" << endl;
    81
    else
    82
    cout << ans << endl;
    83
    }
  2. Number of Ways to Decode the String

  3. You are given a rectangular grid with the bottom left corner as (x1,y1)(x_1, y_1) and the upper right corner as (x2,y2)(x_2, y_2). Find all the lattice points in the grid that are at a maximum distance of rr from the given point (xc,yc)(x_c, y_c). The distance between two points is the cartesian distance between them.

    Constraints:

    • 1x1,y1,x2,y2,xc,yc1061 \leq x_1, y_1, x_2, y_2, x_c, y_c \leq 10^6
    • x1x2x_1 \leq x_2
    • y1y2y_1 \leq y_2
    • 1r1061 \leq r \leq 10^6
    Solution

    Since the coordinates are upto 10610^6 only, we can loop over any one coordinate and then use binary search on the other coordinate to find it’s maximum and minimum possible value that allows it to be within the described circle. If we iterate over the coordinate xx, we need to consider the position ycy_c of the center and thus make three different cases for the same. Refer to the implementation for details. The time complexity of the solution is O(XlogY)O(X \log Y) where X=x2x1X = x_2 - x_1 and Y=y2y1Y = y_2 - y_1.

    1
    bool withinRange(int x1, int y1, int x2, int y2, long long r)
    2
    {
    3
    long long d = pow(x2 - x1, 2) + pow(y2 - y1, 2);
    4
    return d <= r * r;
    5
    }
    6
    7
    // yc < y1
    8
    int getCountLower(int x, int y1, int y2, int xc, int yc, int ra)
    9
    {
    10
    if (!withinRange(x, y1, xc, yc, ra))
    11
    return 0;
    12
    13
    int l = y1, r = y2;
    14
    int ans = -1;
    15
    while (l <= r)
    16
    {
    17
    int m = (l + r) / 2;
    18
    if (withinRange(x, m, xc, yc, ra))
    19
    {
    20
    ans = m;
    21
    l = m + 1;
    22
    }
    23
    else
    24
    r = m - 1;
    25
    }
    26
    return ans - y1 + 1;
    27
    }
    28
    29
    // yc > y2
    30
    int getCountHiger(int x, int y1, int y2, int xc, int yc, int ra)
    31
    {
    32
    if (!withinRange(x, y2, xc, yc, ra))
    33
    return 0;
    34
    35
    int l = y1, r = y2;
    36
    int ans = -1;
    37
    while (l <= r)
    38
    {
    39
    int m = (l + r) / 2;
    40
    if (withinRange(x, m, xc, yc, ra))
    41
    {
    42
    ans = m;
    43
    r = m - 1;
    44
    }
    45
    else
    46
    l = m + 1;
    47
    }
    48
    49
    return y2 - ans + 1;
    50
    }
    51
    52
    // y1 <= yc <= y2
    53
    int getCountMiddle(int x, int y1, int y2, int xc, int yc, int ra)
    54
    {
    55
    if (!withinRange(x, yc, xc, yc, ra))
    56
    return 0;
    57
    58
    // Lower bound
    59
    int l = y1, r = yc;
    60
    int ans1 = -1;
    61
    while (l <= r)
    62
    {
    63
    int m = (l + r) / 2;
    64
    if (withinRange(x, m, xc, yc, ra))
    65
    {
    66
    ans1 = m;
    67
    r = m - 1;
    68
    }
    69
    else
    70
    l = m + 1;
    71
    }
    72
    73
    // Upper bound
    74
    int ans2 = -1;
    75
    l = yc, r = y2;
    76
    while (l <= r)
    77
    {
    78
    int m = (l + r) / 2;
    79
    if (withinRange(x, m, xc, yc, ra))
    80
    {
    81
    ans2 = m;
    82
    l = m + 1;
    83
    }
    84
    else
    85
    r = m - 1;
    86
    }
    87
    88
    return ans2 - ans1 + 1;
    89
    }
    90
    91
    int solve(int x1, int y1, int x2, int y2, int xc, int yc, int r)
    92
    {
    93
    long long ans = 0;
    94
    for (int x = x1; x <= x2; x++)
    95
    {
    96
    if (yc < y1)
    97
    ans += getCountLower(x, y1, y2, xc, yc, r);
    98
    else if (yc > y2)
    99
    ans += getCountHiger(x, y1, y2, xc, yc, r);
    100
    else
    101
    ans += getCountMiddle(x, y1, y2, xc, yc, r);
    102
    }
    103
    104
    return ans;
    105
    }
    Testing Script

    If you want to test your own solution, you can use this script to generate random testcases and compare the output of your solution and the brute force solution.

    int solveBrute(int x1, int y1, int x2, int y2, int xc, int yc, int r)
    {
    int ans = 0;
    for (int x = x1; x <= x2; x++)
    for (int y = y1; y <= y2; y++)
    if (withinRange(x, y, xc, yc, r))
    ans++;
    return ans;
    }
    int main()
    {
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    int testCount = 2000;
    int x1 = 50, y1 = 50, x2 = 150, y2 = 150;
    for (int t = 0; t < testCount; t++)
    {
    int xc = uniform_int_distribution<int>(50, 250)(rng);
    int yc = uniform_int_distribution<int>(-50, 250)(rng);
    int r = uniform_int_distribution<int>(0, 200)(rng);
    int a1 = solve(x1, y1, x2, y2, xc, yc, r);
    int a2 = solveBrute(x1, y1, x2, y2, xc, yc, r);
    if (a1 != a2)
    {
    cout << "Mismatched " << t + 1 << endl;
    cout << x1 << " " << y1 << " " << x2 << " " << y2 << " " << xc << " " << yc << " " << r << endl;
    cout << a1 << " " << a2 << endl;
    return 0;
    }
    }
    cout << "Passed" << endl;
    return 0;
    }
  4. You are given an undirected and connected graph with nn nodes. Intially you are at node 11, and need to travel to node nn. There are power boosters at kk nodes, and every time you arrive at a power booster node, your power is set to pp, which allows you to walk cross pp edges. What is the minimum value of pp such that you can reach node nn from node 11?

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1k1051 \leq k \leq 10^5
    Non Optimal Solution

    As with such minimization questions, we will use binary search to find the minimum value of pp. Once we have a value of pp, we can use a simple Djikstra to find if a valid path exists. The only change we need to make is if we arrive at a power booster node, we need to set the power to pp instead of further decrementing it.

    You might expect the time complexity of the solution to be O(mlognlogm)O(m \log n \cdot \log m) where mm is the maximum number of edges in the graph due to Djikstra, but the same turns out to be in the order of O(n2)O(n^2) instead. This is because having power booster breaks the monotonicity of the distance function that Djikstra expects (Suppose you reach an intermediary power node that is still at a large distance from destination before the other power node that is at a smaller distance. Now you will recharge at that node (farther from destination) and do Djikstra from it which would be of no use as it is suboptimal and may not be able to reach the final destination from there)

    int main()
    {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> g(n);
    for (int i = 0; i < m; i++)
    {
    int u, v;
    cin >> u >> v;
    u--, v--;
    g[u].push_back(v);
    g[v].push_back(u);
    }
    int k;
    cin >> k;
    vector<int> power(n, 0);
    for (int i = 0; i < k; i++)
    {
    int x;
    cin >> x;
    x--;
    power[x] = 1;
    }
    auto check = [&](int p) -> bool
    {
    vector<int> dis(n, -1);
    priority_queue<pair<int, int>> pq;
    pq.push({p, 0});
    dis[0] = p;
    while (!pq.empty())
    {
    auto [ops, node] = pq.top();
    pq.pop();
    if (dis[node] != ops)
    continue;
    if (node == n - 1)
    return 1;
    if (power[node])
    ops = p;
    if (ops == 0)
    continue;
    for (int v : g[node])
    {
    if (dis[v] < ops - 1)
    {
    dis[v] = ops - 1;
    pq.push({ops - 1, v});
    }
    }
    }
    return 0;
    };
    int l = 1, r = m;
    int ans = -1;
    while (l <= r)
    {
    int mid = (l + r) / 2;
    if (check(mid))
    {
    ans = mid;
    r = mid - 1;
    }
    else
    l = mid + 1;
    }
    cout << ans << endl;
    }
    Optimal Solution

    We will binary seach on the value of pp. To check for a particular value of pp, we will construct an new graph with the nodes 11, nn, and all the nodes which are at a distance of ceil(p/2)\leq ceil(p / 2) from any power node. We will then just run a BFS to check if a path exists from 11 to nn in this new graph. The time complexity of the solution is O((n+m)logm)O((n + m)\log m).

    1
    int main()
    2
    {
    3
    int n, m;
    4
    cin >> n >> m;
    5
    6
    vector<vector<int>> g(n);
    7
    vector<pair<int, int>> edges;
    8
    for (int i = 0; i < m; i++)
    9
    {
    10
    int u, v;
    11
    cin >> u >> v;
    12
    u--, v--;
    13
    g[u].push_back(v);
    14
    g[v].push_back(u);
    15
    edges.push_back({u, v});
    16
    }
    17
    18
    int k;
    19
    cin >> k;
    20
    vector<int> power;
    21
    for (int i = 0; i < k; i++)
    22
    {
    23
    int x;
    24
    cin >> x;
    25
    power.push_back(x - 1);
    26
    }
    27
    // Can consider n - 1 as power node as well
    28
    power.push_back(n - 1);
    29
    30
    auto check = [&](int p) -> bool
    31
    {
    32
    vector<int> dis(n, -1);
    33
    queue<int> q;
    34
    for (int x : power)
    35
    {
    36
    dis[x] = 0;
    37
    q.push(x);
    38
    }
    39
    40
    // Calculate distance from power nodes
    41
    int curDis = 0;
    42
    while (!q.empty())
    43
    {
    44
    int sz = q.size();
    45
    curDis++;
    46
    if (curDis > (p + 1) / 2)
    47
    break;
    48
    49
    while (sz--)
    50
    {
    51
    int u = q.front();
    52
    q.pop();
    53
    54
    for (int v : g[u])
    55
    {
    56
    if (dis[v] != -1)
    57
    continue;
    58
    dis[v] = curDis;
    59
    q.push(v);
    60
    }
    61
    }
    62
    }
    63
    64
    // Build the new graph
    65
    vector<vector<int>> gn(n);
    66
    for (auto [u, v] : edges)
    67
    if (dis[u] != -1 && dis[v] != -1)
    68
    {
    69
    gn[u].push_back(v);
    70
    gn[v].push_back(u);
    71
    }
    72
    73
    // Perform BFS to check if the node is reachable
    74
    vector<int> vis(n, 0);
    75
    queue<int> q2;
    76
    q2.push(0);
    77
    vis[0] = 1;
    78
    79
    while (!q2.empty())
    80
    {
    81
    int u = q2.front();
    82
    q2.pop();
    83
    if (u == n - 1)
    84
    return 1;
    85
    86
    for (int v : gn[u])
    87
    {
    88
    if (vis[v])
    89
    continue;
    90
    vis[v] = 1;
    91
    q2.push(v);
    92
    }
    93
    }
    94
    95
    return 0;
    96
    };
    97
    98
    int l = 1, r = m;
    99
    int ans = -1;
    100
    while (l <= r)
    101
    {
    102
    int mid = (l + r) / 2;
    103
    if (check(mid))
    104
    {
    105
    ans = mid;
    106
    r = mid - 1;
    107
    }
    108
    else
    109
    l = mid + 1;
    110
    }
    111
    112
    cout << ans << endl;
    113
    }
  5. Count Number of Good Subsets

    Solution

    Since it is clear that only each number can be used at most once in a valid subset, we can maintain a map of the frequency of the elements present. We will use a bitmask to show which all prime numbers have been already been used in our product, and keep the other state as the number we are trying to add to the answer. The main trick behind the question is to first ignore all the occurences of 11, and then add them later to the sets achieved by the other numbers. The time complexity of the solution is O(210102+log(A))O(2^{10} \cdot 10^2 + log(A)) where AA is the count of maximum occurences of 11, which can be nn in the worst case.

    1
    class Solution
    2
    {
    3
    vector<int> primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
    4
    long long mod = 1e9 + 7;
    5
    vector<vector<long long>> dp;
    6
    7
    long long binPow(long long a, long long b, long long m)
    8
    {
    9
    long long ans = 1;
    10
    while (b)
    11
    {
    12
    if (b & 1)
    13
    ans = (ans * a) % m;
    14
    a = (a * a) % m;
    15
    b >>= 1;
    16
    }
    17
    18
    return ans;
    19
    }
    20
    21
    pair<bool, int> getNewMask(int mask, int n)
    22
    {
    23
    for (int i = 0; i < 10; i++)
    24
    if (n % primes[i] == 0)
    25
    {
    26
    if (n % (primes[i] * primes[i]) == 0)
    27
    return {0, 0};
    28
    if ((mask >> i) & 1)
    29
    return {0, 0};
    30
    mask |= (1 << i);
    31
    }
    32
    33
    return {1, mask};
    34
    }
    35
    36
    long long solve(int n, int mask, map<int, long long> &cnt)
    37
    {
    38
    if (n == 31)
    39
    return mask != 0;
    40
    if (dp[n][mask] != -1)
    41
    return dp[n][mask];
    42
    43
    long long ans = solve(n + 1, mask, cnt);
    44
    auto x = getNewMask(mask, n);
    45
    if (x.first)
    46
    ans += (solve(n + 1, x.second, cnt) * cnt[n]) % mod;
    47
    48
    return dp[n][mask] = ans % mod;
    49
    }
    50
    51
    public:
    52
    int numberOfGoodSubsets(vector<int> &nums)
    53
    {
    54
    dp.assign(31, vector<long long>(1 << 10, -1));
    55
    56
    map<int, long long> freq;
    57
    for (int x : nums)
    58
    freq[x]++;
    59
    60
    long long ans = solve(2, 0, freq);
    61
    ans *= binPow(2, freq[1], mod);
    62
    ans %= mod;
    63
    64
    return ans;
    65
    }
    66
    };

Online Assessment Questions

  1. Same question as Deutsche Bank: Question 1313 from the Other Campus Questions section.

  2. You are given upto qq queries of the type [l,r,k][l, r, k], where in you have to find the kthk^{th} beautiful number between ll and rr. A number is said to be beautiful if it contains the substring 101101 in it’s binary representation.

    • 1q2001 \leq q \leq 200
    • 1lr10181 \leq l \leq r \leq 10^{18}
    • 1k10181 \leq k \leq 10^{18}

Netradyne

The test usually involves 2 coding questions and 1 question involving writing a SQL query. The rest are MCQs from topics like:

Other Campus Questions

  1. The map contains islands named from 11 to nn. For any two islands ii and jj, you can go to jj from ii only if ii divides jj. Find the number of ways to reach island nn starting from island 11. You can’t move from island ii to ii. There are tt test cases, each denoted by a single integer nn, the island that you have to reach.

    Constraints:

    • 1t1051 \leq t \leq 10^5
    • 1n1061 \leq n \leq 10^6
    Solution

    We can use a simple sieve like approach to compute all the divisors of all the numbers upto 10610^6 and then use a simple DP to precompute the number of ways for all the possible nn. Then answering any query takes just O(1)O(1) time. The time complexity of the solution is O(AlogA+T)O(A \log A + T) where A=max(N)A = max(N).

    1
    int main()
    2
    {
    3
    const int MAXN = 1e6 + 10;
    4
    5
    long long MOD = 1e9 + 7;
    6
    vector<long long> dp(MAXN, 0);
    7
    dp[1] = 1;
    8
    for (int i = 1; i < MAXN; i++)
    9
    {
    10
    for (int j = 2 * i; j < MAXN; j += i)
    11
    {
    12
    dp[j] += dp[i];
    13
    dp[j] %= MOD;
    14
    }
    15
    }
    16
    17
    int t;
    18
    cin >> t;
    19
    while (t--)
    20
    {
    21
    int n;
    22
    cin >> n;
    23
    cout << dp[n] <<details endl;
    24
    }
    25
    }
  2. You are given an array of nn elements. In each step, you need to take the sum of the numbers at the odd indexes of the array (11 indexed), and remove all the even elements. Do this until only 11 element is left in the array. What is the final sum obtained?

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 109arr[i]109-10^9 \leq arr[i] \leq 10^9
    Solution

    Writing the pattern for a couple of arrays by hand, we realize only the elements at index ii such that ii % 2^k = 1 are added to the answer for every possible value of kk greater than 00. Thus we can writing a simple simulation in $O(n \log n) time.

    int main()
    {
    int n;
    cin >> n;
    vector<int> arr(n + 1);
    for (int i = 1; i <= n; i++)
    cin >> arr[i];
    long long ans = 0;
    for (int pow2 = 2; pow2 <= 2 * n; pow2 *= 2)
    for (int i = 1; i <= n; i++)
    if (i % pow2 == 1)
    ans += arr[i];
    cout << ans << endl;
    }
  3. You are given an array of length nn. You need to all the subsequences of the same of length mm, and then calculate the score of the subsequence as the product of the first and last element of the subsequence. Return the minimum possible score of any subsequence.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 109arr[i]109-10^9 \leq arr[i] \leq 10^9

Online Assessment Questions

  1. You are given an integer as a string ss. In each iteration, you need to take the sum of the digits of the number with have their index divisible by kk. Treat the obtained number as the original string and repeat this untill you obtain a simple digit sum. Return the same.

  2. You are looking to hire nn frontend and mm backend developers. There are n+mn + m candidates, each of which can be hired either as a frontend or backend developer. The cost of hiring the ithi^{th} candidate as a frontend developer is f[i]f[i] and the cost of hiring the ithi^{th} candidate as a backend developer is b[i]b[i]. Find the minimum cost of hiring nn frontend and mm backend developers.

    Constraints:

    • 1n,m1041 \leq n, m \leq 10^4
    • 1f[i],b[i]1091 \leq f[i], b[i] \leq 10^9
  3. There was 11 MCQ on aptitude, 11 simple SQL query writing question, and 1414 MCQs from OS, C++ and data structures. A couple of the MCQ questions were repeated from the questions from other campuses.


Microsoft

Other Campus Questions

  1. Reorient Edges to Make All Paths Lead to Zero

  2. You are given mm square tiles of size 1×11 \times 1 and nn square tiles of size 2×22 \times 2. Your task is to create the largest square possible using the given tiles. The tiles can not overlap, and the resulting square can not have empty spaces in between. Return the side length of the square.

    Constraints:

    • 1m,n1091 \leq m, n \leq 10^9
    Solution

    The key trick to realize is that if try to binary search over the length of the longest side of the square ss, then the function would be moontonic sepearately for the cases of even and odd side lengths. This is due to the difference in the optimal greedy strategy to construct the squares:

    1. For odd side lengths, you atleast need 2s12s - 1 tiles of size 1×11 \times 1 that can be used to fill two adjacent edges, and then you can fill the even square of side s1s - 1 with the remaining tiles.
    2. For the even sides, use as many as possible tiles of size 2×22 \times 2 to fill the square, and then fill the remaining gaps with the tiles of size 1×11 \times 1.

    Then we can simply perform two binary searches to find the maximum possible side length of the square. The time complexity of the solution is O(logA)O(\log A) where AA is the maximum possible side length of the square.

    1
    int main()
    2
    {
    3
    using ll = long long;
    4
    5
    ll n, m;
    6
    cin >> n >> m;
    7
    8
    auto checkEvenSide = [&](ll s, ll n, ll m) -> bool
    9
    {
    10
    ll use2Sq = min(m, (s * s) / 4LL);
    11
    ll needOneSq = s * s - 4LL * use2Sq;
    12
    return needOneSq <= n;
    13
    };
    14
    15
    auto checkOddSide = [&](ll s, ll n, ll m) -> bool
    16
    {
    17
    ll minOneSq = 2LL * s - 1;
    18
    if (n < minOneSq)
    19
    return 0;
    20
    21
    return checkEvenSide(s - 1, n - minOneSq, m);
    22
    };
    23
    24
    ll ansOdd = 0, l = 1, r = 1e9;
    25
    while (l <= r)
    26
    {
    27
    ll mid = (l + r) / 2;
    28
    if (checkOddSide(2LL * mid + 1, n, m))
    29
    {
    30
    ansOdd = 2LL * mid + 1;
    31
    l = mid + 1;
    32
    }
    33
    else
    34
    r = mid - 1;
    35
    }
    36
    37
    ll ansEven = 0;
    38
    l = 0, r = 1e9;
    39
    while (l <= r)
    40
    {
    41
    ll mid = (l + r) / 2;
    42
    if (checkEvenSide(2LL * mid, n, m))
    43
    {
    44
    ansEven = 2LL * mid;
    45
    l = mid + 1;
    46
    }
    47
    else
    48
    r = mid - 1;
    49
    }
    50
    51
    cout << max(ansOdd, ansEven) << endl;
    52
    }
  3. There is string of length nn consiting only of characters aa. Whenever there are two identical adjacent letters, they can be merged together to form the next alphabet (for example, aaaa can be converted to bb). The letter pair zzzz can be merged. What is the lexographically maximum string you can obtain by applying the operations optimally?

    Constraints:

    • 1n1091 \leq n \leq 10^9
    Solution
    1
    int main()
    2
    {
    3
    int n;
    4
    cin >> n;
    5
    6
    string s = "";
    7
    while (n)
    8
    {
    9
    int maxP = log2(n);
    10
    char ch = 'a' + min(maxP, 25);
    11
    n -= (1 << min(maxP, 25));
    12
    s += ch;
    13
    }
    14
    cout << s << "\n";
    15
    }
  4. Strings with long blocks of repeating characters take much less space if kept in a compressed representation. To obtain the compressed representation, we replace each segment of equal characters in the string with the number of characters in the segment followed by the character (for example, we replace segment CCCC with 4C). To avoid increasing the size, we leave the one-letter segments unchanged (the compressed representation of BC is the same string BC).

    For example, the compressed representation of the string ABBBCCDDCCC is A382C2D3C, and the compressed representation of the string AAAAAAAAAAABXXAAAAAAAAAA is 11AB2X10A. In order increase the compression further, we decided to modify our compression algorithm. Now, before compression, we remove exactly KK consecutive letters from the input string. We would like to know the shortest compressed form that we can generate this way.

    Constraints:

    • 1s1051 \leq |s| \leq 10^5
    • 1Kn1 \leq K \leq n
    Solution
    1
    int getLen(int n)
    2
    {
    3
    int cnt = 0;
    4
    while (n)
    5
    {
    6
    cnt++;
    7
    n /= 10;
    8
    }
    9
    return cnt;
    10
    }
    11
    12
    int getCont(int n)
    13
    {
    14
    if (n == 1)
    15
    return 1;
    16
    return 1 + getLen(n);
    17
    }
    18
    19
    int main()
    20
    {
    21
    string s;
    22
    cin >> s;
    23
    s = "$" + s + "#";
    24
    int n = s.size();
    25
    26
    int k;
    27
    cin >> k;
    28
    29
    vector<int> compId(n), suff(n), segs;
    30
    for (int i = 0, id = 0; i < n; i++)
    31
    {
    32
    int st = i;
    33
    while (i + 1 < n && s[i + 1] == s[i])
    34
    i++;
    35
    int len = i - st + 1;
    36
    segs.push_back(len);
    37
    38
    for (int j = st; j <= i; j++)
    39
    {
    40
    suff[j] = len;
    41
    len--;
    42
    compId[j] = id;
    43
    }
    44
    id++;
    45
    }
    46
    47
    int m = segs.size();
    48
    vector<int> segSuff(m + 1);
    49
    for (int i = m - 1; i >= 0; i--)
    50
    segSuff[i] = segSuff[i + 1] + getCont(segs[i]);
    51
    52
    int ans = n;
    53
    54
    int prevLen = 0, fre = 1;
    55
    char curChar = s[0];
    56
    57
    for (int i = 0; i < n; i++)
    58
    {
    59
    int endIdx = i + k + 1;
    60
    if (endIdx >= n)
    61
    break;
    62
    63
    int segId = compId[endIdx];
    64
    int addLen = segSuff[segId + 1];
    65
    int curAns;
    66
    67
    if (curChar == s[endIdx])
    68
    curAns = prevLen + addLen + getCont(fre + suff[endIdx]);
    69
    else
    70
    curAns = prevLen + addLen + getCont(fre) + getCont(suff[endIdx]);
    71
    ans = min(ans, curAns);
    72
    73
    if (s[i + 1] == s[i])
    74
    fre++;
    75
    else
    76
    {
    77
    prevLen += getCont(fre);
    78
    fre = 1;
    79
    curChar = s[i + 1];
    80
    }
    81
    }
    82
    83
    cout << ans - 2 << "\n";
    84
    }
  5. In this task, you are given two strings of digits that represent (possibly very large) Integers. Your goal is to make those numbers as close to one another as possible. In other words, you want to minimize the absolute value of their difference. You can swap some of the corresponding digits (e.g. the first digit of the first the first digit of the second number, the second digit of the first number with the second digit of the second number, etc.). Swapping the digita is an extremely tiring task, so you want to make as few swaps as possible. Write a function that, given two strings SS and TT, both of length NN, returns the minimum number of swaps needed to minimize the difference between the two numbers represented by the input strings.

    Constraints:

    • 1N1051 \leq N \leq 10^5
    Solution
    1
    int main()
    2
    {
    3
    string s, t;
    4
    cin >> s >> t;
    5
    6
    if (s == t)
    7
    {
    8
    cout << 0;
    9
    return 0;
    10
    }
    11
    12
    int n = s.size();
    13
    14
    int fnd = 0;
    15
    int gr1 = 0, gr2 = 0;
    16
    for (int i = 0; i < n; i++)
    17
    {
    18
    if (s[i] == t[i])
    19
    continue;
    20
    21
    if (!fnd)
    22
    {
    23
    if (s[i] > t[i])
    24
    fnd = 1;
    25
    else
    26
    fnd = 2;
    27
    continue;
    28
    }
    29
    30
    if (s[i] > t[i])
    31
    gr1++;
    32
    else
    33
    gr2++;
    34
    }
    35
    36
    cout << min(gr1 + (fnd != 1), gr2 + (fnd == 1)) << "\n";
    37
    }
  6. There is an array AA of NN integers. What is the largest sum of two numbers which do not have any common digits? If it is impossible to choose two such numbers, the function should return 1-1.

    Constraints:

    • 1N21051 \leq N \leq 2 \cdot 10^5
    • 1A[i]1091 \leq A[i] \leq 10^9
    Solution
    1
    int main()
    2
    {
    3
    int n;
    4
    cin >> n;
    5
    6
    vector<int> arr(n);
    7
    for (int i = 0; i < n; i++)
    8
    cin >> arr[i];
    9
    10
    vector<long long> mx(1 << 10, -1e18);
    11
    for (int i = 0; i < n; i++)
    12
    {
    13
    int m = 0;
    14
    if (arr[i] == 0)
    15
    m = 1;
    16
    17
    int v = arr[i];
    18
    while (v)
    19
    {
    20
    int d = v % 10;
    21
    m |= (1 << d);
    22
    v /= 10;
    23
    }
    24
    25
    mx[m] = max(mx[m], (long long)arr[i]);
    26
    }
    27
    28
    long long ans = -1e18;
    29
    for (int m1 = 0; m1 < (1 << 10); m1++)
    30
    {
    31
    if (mx[m1] == -1e18)
    32
    continue;
    33
    34
    for (int m2 = m1 + 1; m2 < (1 << 10); m2++)
    35
    {
    36
    if (mx[m2] == -1e18)
    37
    continue;
    38
    if ((m1 & m2) == 0)
    39
    ans = max(ans, (long long)mx[m1] + mx[m2]);
    40
    }
    41
    }
    42
    43
    cout << max(ans, -1LL) << "\n";
    44
    }
  7. Minimum Cost to Equalize Array

Online Assessment Questions

  1. You are given nn strings of length kk each. You need to form a string of length kk such that all the strings differ from the same by atmost 11 character. If it is not possible to form such a string, return an empty string.

    Constraints:

    • 1n1061 \leq n \leq 10^6
    • 1k1061 \leq k \leq 10^6
    • 1nk1061 \leq n \cdot k \leq 10^6
    • The strings consist of lowercase English alphabets only.
  2. You are given a grid of size 2×n2 \times n. You need to start from (0,0)(0,0) and need to reach the cell (1,n1)(1, n - 1). You can only move rightwards and downwards. The cost of this path is the maximum value of the grid that comes in the path. Find the minimum cost of the path.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1grid[i][j]1091 \leq grid[i][j] \leq 10^9

Google

Other Campus Questions

  1. You are given an array arrarr of length nn and two number mm and ll. You can perform at max mm operations on the array, where in one operation you can select any subarray of arrarr of length at most ll, and decrement the value of all elements of the subarray by 11. Determine the minimum value of the maximum element present in the array if the operations are performed optimally.
  1. You are given a graph (not necessarily connected) of nn nodes numbered from 11 to nn and n1n - 1 edges. Each edge has a cost associated with it. You can break any edge, disconnecting the pair of nodes in one operation, but you must add the same edge between a different pair od nodes. The cost of one such operation is the cost of the edge. Find the minimum cost to make the graph a tree.

    • 1n1051 \leq n \leq 10^5
    • 1cost[i]1091 \leq cost[i] \leq 10^9
    • The graph may contain self loops and multiple edges between the same pair of nodes.
    Solution

    Since the final connected graph must be a tree, we can make minor modifications to the algorithm for the Maximum Spanning Tree. We will iterate over the edges in the decreasing order of their cost, and only change the edges are present between some already connected components. We won’t add these edges to any component just yet, as it would be optimal to hold of them till the end, and then connect the disconnected components with them. We can use the DSU data structure to keep track of the connected components. The time complexity of the solution is O(nlogn)O(n \log n).

    1
    class DSU
    2
    {
    3
    int n;
    4
    vector<int> parent, size;
    5
    6
    public:
    7
    DSU(int n)
    8
    {
    9
    this->n = n;
    10
    parent.resize(n);
    11
    size.resize(n, 1);
    12
    for (int i = 0; i < n; i++)
    13
    parent[i] = i;
    14
    }
    15
    16
    int find(int u)
    17
    {
    18
    if (parent[u] == u)
    19
    return u;
    20
    return parent[u] = find(parent[u]);
    21
    }
    22
    23
    void merge(int u, int v)
    24
    {
    25
    int pu = find(u), pv = find(v);
    26
    if (pu == pv)
    27
    return;
    28
    if (size[pu] < size[pv])
    29
    swap(pu, pv);
    30
    parent[pv] = pu;
    31
    size[pu] += size[pv];
    32
    }
    33
    };
    34
    35
    int solve(int n, vector<vector<int>> &edges)
    36
    {
    37
    sort(edges.begin(), edges.end(), [](vector<int> &a, vector<int> &b)
    38
    { return a[2] > b[2]; });
    39
    40
    DSU dsu(n + 1);
    41
    int ans = 0;
    42
    for (auto &e : edges)
    43
    {
    44
    int u = e[0], v = e[1], w = e[2];
    45
    if (dsu.find(u) != dsu.find(v))
    46
    dsu.merge(u, v);
    47
    else
    48
    ans += w;
    49
    }
    50
    51
    return ans;
    52
    }

Online Assessment Questions

  1. You are given an array arrarr of length nn. You need to count the number of quadruples (i,j,k,l)(i, j, k, l) such that ijkli \leq j \leq k \leq l and arr[i]arr[k]=arr[j]arr[l]arr[i] \cdot arr[k] = arr[j] \cdot arr[l].

    Constraints:

    • 1n10001 \leq n \leq 1000
    • 1arr[i]1091 \leq arr[i] \leq 10^9
    Solution
    1
    int main()
    2
    {
    3
    int t;
    4
    cin >> t;
    5
    6
    auto get = [](int a, int b) -> pair<int, int>
    7
    {
    8
    int g = __gcd(a, b);
    9
    return {a / g, b / g};
    10
    };
    11
    12
    while (t--)
    13
    {
    14
    int n;
    15
    cin >> n;
    16
    17
    vector<int> arr(n);
    18
    for (int i = 0; i < n; i++)
    19
    cin >> arr[i];
    20
    21
    // p / q = s / r
    22
    map<pair<int, int>, int> cnt;
    23
    cnt[get(arr[0], arr[1])]++;
    24
    int ans = 0;
    25
    26
    for (int i = 2; i < n; i++)
    27
    {
    28
    for (int j = i + 1; j < n; j++)
    29
    ans += cnt[get(arr[j], arr[i])];
    30
    31
    for (int j = 0; j < i; j++)
    32
    cnt[get(arr[j], arr[i])]++;
    33
    }
    34
    35
    cout << ans << "\n";
    36
    }
    37
    }
  2. You are given an array of size nn and an integer kk. You want to divide the array arrarr into kk non-empty contiguous subarrays such that each subarray is a good subarray. A good subarray has the absolute difference between any two elements in that array to be greater than or equal to XX. A singleton array is by default a good subarray.

    What is the maximum possible value of XX such that the division is possible?

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1kn1 \leq k \leq n
    • 106arr[i]106-10^6 \leq arr[i] \leq 10^6
    Solution
    int getCnt(vector<int> &arr, int n, int ma)
    {
    int cnt = 0;
    for (int i = 0; i < n; i++)
    {
    set<int> s;
    s.insert(arr[i]);
    while (i + 1 < n)
    {
    auto itr = s.lower_bound(arr[i + 1]);
    if (itr != s.end() && *itr - arr[i + 1] < ma)
    break;
    if (itr != s.begin())
    {
    itr--;
    if (arr[i + 1] - *itr < ma)
    break;
    }
    i++;
    s.insert(arr[i]);
    }
    cnt++;
    }
    return cnt;
    }
    void solve()
    {
    int n;
    cin >> n;
    vector<int> arr(n);
    for (int i = 0; i < n; i++)
    cin >> arr[i];
    int k;
    cin >> k;
    int l = 0, r = *max_element(arr.begin(), arr.end()) - *min_element(arr.begin(), arr.end());
    int ans = 0;
    while (l <= r)
    {
    int mid = (l + r) / 2;
    auto cnt = getCnt(arr, n, mid);
    if (cnt == k)
    {
    ans = mid;
    l = mid + 1;
    }
    else if (cnt < k)
    l = mid + 1;
    else
    r = mid - 1;
    }
    cout << ans << endl;
    }
    int main()
    {
    int t;
    cin >> t;
    while (t--)
    solve();
    }
  3. Lexographically Smallest Beautiful String

    Solution
    1
    class Solution {
    2
    public:
    3
    string smallestBeautifulString(string s, int k) {
    4
    int n = s.size();
    5
    6
    auto check = [&](int idx) -> bool {
    7
    return (
    8
    idx == 0
    9
    || (idx == 1 && s[idx] != s[idx - 1])
    10
    || (idx >= 2 && s[idx] != s[idx - 1] && s[idx] != s[idx - 2])
    11
    );
    12
    };
    13
    14
    int idx = s.size() - 1;
    15
    while (idx >= 0) {
    16
    s[idx]++;
    17
    if (s[idx] - 'a' == k)
    18
    idx--;
    19
    else if (check(idx))
    20
    break;
    21
    }
    22
    23
    if (idx < 0)
    24
    return "";
    25
    26
    string rep = "abc";
    27
    for (int j = idx + 1; j < n; j++) {
    28
    for (int c: rep) {
    29
    s[j] = c;
    30
    if (check(j))
    31
    break;
    32
    }
    33
    }
    34
    35
    return s;
    36
    }
    37
    };

Plutus Research

Other Campus Questions

  1. Given two integers ll and rr (lrl \leq r) and kk, find the minimum value xx between ll and rr such that sum of digits of all numbers between ll and xx is at least kk. Its given that at least one such xx exists.

    • l1015l \leq 10^{15}
    • r1015r \leq 10^{15}
    Solution

    We will try to binary search on the answer. If the current answer is xx, we need to check if the count of digits in the range [l,x][l, x] is atleast kk or not. The same can be calculated by finding a function to give the sum of the digits of the numbers in the range [0,x][0, x], which will use digit DP to calculate the same. The time complexity of the solution is log(1015152)\log(10^{15} \cdot 15 \cdot 2).

    1
    // Returns <count, sum>
    2
    pair<long long, long long> solve(int idx, bool eq, string &num, pair<long long, long long> dp[][2])
    3
    {
    4
    if (idx == num.size())
    5
    return {1, 0};
    6
    if (dp[idx][eq].first != -1)
    7
    return dp[idx][eq];
    8
    9
    long long sum = 0, ways = 0;
    10
    int mx = eq ? num[idx] - '0' : 9;
    11
    for (long long i = 0; i <= mx; i++)
    12
    {
    13
    bool newEq = eq && i == mx;
    14
    auto p = solve(idx + 1, newEq, num, dp);
    15
    ways += p.first;
    16
    sum += p.second + p.first * i;
    17
    }
    18
    19
    return dp[idx][eq] = {ways, sum};
    20
    }
    21
    22
    long long getSum(long long x)
    23
    {
    24
    if (x <= 0)
    25
    return 0;
    26
    27
    string num = to_string(x);
    28
    pair<long long, long long> dp[num.size() + 1][2];
    29
    memset(dp, -1, sizeof(dp));
    30
    31
    auto p = solve(0, 1, num, dp);
    32
    return p.second;
    33
    }
    34
    35
    int main()
    36
    {
    37
    long long l, r, k;
    38
    cin >> l >> r >> k;
    39
    40
    long long cnt1 = getSum(l - 1);
    41
    long long low = l, high = r, ans = -1;
    42
    while (low <= high)
    43
    {
    44
    long long mid = (low + high) / 2;
    45
    long long cnt2 = getSum(mid) - cnt1;
    46
    if (cnt2 >= k)
    47
    {
    48
    ans = mid;
    49
    high = mid - 1;
    50
    }
    51
    else
    52
    low = mid + 1;
    53
    }
    54
    55
    cout << ans << endl;
    56
    }
  2. Given an array aa of size nn, find the number of subarrays whose product of the minimum value and the maximum value is divisuble by the length of subarray.

    • 1n1051 \leq n \leq 10^5
    • 1a[i]301 \leq a[i] \leq 30
    Solution

    Since the maximum value of the array is 3030, the maximum possible product of the minimum and maximum value of the subarray is 30×30=90030 \times 30 = 900. We can iterate over all the possible subarrays of length at most 900900 and count the number of subarrays that satisfy the condition. We will use deque to maintain the minimum and maximum in the current subarray. The time complexity of the solution is O(min(n,900)2)O(min(n, 900)^2).

    1
    int main()
    2
    {
    3
    int n;
    4
    cin >> n;
    5
    6
    vector<int> arr(n);
    7
    for (int i = 0; i < n; i++)
    8
    cin >> arr[i];
    9
    10
    int cnt = 0;
    11
    for (int len = 1; len <= min(n, 900); len++)
    12
    {
    13
    deque<int> minDq, maxDq;
    14
    for (int i = 0; i < n; i++)
    15
    {
    16
    while (!minDq.empty() && minDq.front() <= i - len)
    17
    minDq.pop_front();
    18
    while (!maxDq.empty() && maxDq.front() <= i - len)
    19
    maxDq.pop_front();
    20
    21
    while (!minDq.empty() && arr[minDq.back()] >= arr[i])
    22
    minDq.pop_back();
    23
    while (!maxDq.empty() && arr[maxDq.back()] <= arr[i])
    24
    maxDq.pop_back();
    25
    26
    minDq.push_back(i);
    27
    maxDq.push_back(i);
    28
    29
    if (i >= len - 1)
    30
    {
    31
    int prod = arr[maxDq.front()] * arr[minDq.front()];
    32
    if (prod % len == 0)
    33
    cnt++;
    34
    }
    35
    }
    36
    }
    37
    38
    cout << cnt << endl;
    39
    }
  3. Given a tree of nn nodes rooted at 11 and an array of integers aa, you need to process qq queries of the form v x. For each query you need to tell the maximum length of the matching prefix (from the MSB to LSB) of vv and any of the aa values of the nodes that lie on the path from the root to the node xx (all ancestors of xx and xx). Each number is represented in 3030 bits.

    • 1n1051 \leq n \leq 10^5
    • 1q1051 \leq q \leq 10^5
    • 1a[i]1091 \leq a[i] \leq 10^9
    • 1v1091 \leq v \leq 10^9
    Solution

    We can use a bit trie to store the binary representation of the numbers. We can then use the trie to answer the queries in O(30)O(30) time while performing a DFS on the tree. The time complexity of the solution is O(n+30q)O(n + 30 * q).

    1
    class Node
    2
    {
    3
    public:
    4
    vector<int> ch;
    5
    int cnt;
    6
    7
    Node() : ch(vector<int>(2, -1)), cnt(0) {}
    8
    };
    9
    10
    class Trie
    11
    {
    12
    vector<Node> nodes;
    13
    14
    public:
    15
    Trie()
    16
    {
    17
    nodes.push_back(Node());
    18
    }
    19
    20
    void add(int x)
    21
    {
    22
    int cur = 0;
    23
    for (int bit = 29; bit >= 0; bit--)
    24
    {
    25
    int u = (x >> bit) & 1;
    26
    if (nodes[cur].ch[u] == -1)
    27
    {
    28
    nodes[cur].ch[u] = nodes.size();
    29
    nodes.push_back(Node());
    30
    }
    31
    cur = nodes[cur].ch[u];
    32
    nodes[cur].cnt++;
    33
    }
    34
    }
    35
    36
    void remove(int x)
    37
    {
    38
    int cur = 0;
    39
    for (int bit = 29; bit >= 0; bit--)
    40
    {
    41
    int u = (x >> bit) & 1;
    42
    cur = nodes[cur].ch[u];
    43
    nodes[cur].cnt--;
    44
    }
    45
    }
    46
    47
    int get(int x)
    48
    {
    49
    int cur = 0;
    50
    int len = 0;
    51
    for (int bit = 29; bit >= 0; bit--)
    52
    {
    53
    int u = (x >> bit) & 1;
    54
    if (nodes[cur].ch[u] == -1)
    55
    return len;
    56
    cur = nodes[cur].ch[u];
    57
    if (nodes[cur].cnt == 0)
    58
    return len;
    59
    len++;
    60
    }
    61
    return len;
    62
    }
    63
    };
    64
    65
    int main()
    66
    {
    67
    int n;
    68
    cin >> n;
    69
    70
    vector<vector<int>> g(n);
    71
    for (int i = 0; i < n - 1; i++)
    72
    {
    73
    int u, v;
    74
    cin >> u >> v;
    75
    u--, v--;
    76
    g[u].push_back(v);
    77
    g[v].push_back(u);
    78
    }
    79
    80
    vector<int> arr(n);
    81
    for (int i = 0; i < n; i++)
    82
    cin >> arr[i];
    83
    84
    int q;
    85
    cin >> q;
    86
    87
    vector<vector<pair<int, int>>> qByNode(n);
    88
    for (int i = 0; i < q; i++)
    89
    {
    90
    int x, v;
    91
    cin >> x >> v;
    92
    qByNode[x - 1].push_back({v, i});
    93
    }
    94
    95
    vector<int> ans(q);
    96
    Trie t;
    97
    98
    function<void(int, int)> dfs = [&](int u, int p) -> void
    99
    {
    100
    t.add(arr[u]);
    101
    for (auto [v, idx] : qByNode[u])
    102
    ans[idx] = t.get(v);
    103
    104
    for (int v : g[u])
    105
    {
    106
    if (v == p)
    107
    continue;
    108
    dfs(v, u);
    109
    }
    110
    111
    t.remove(arr[u]);
    112
    };
    113
    dfs(0, -1);
    114
    115
    for (auto x : ans)
    116
    cout << x << "\n";
    117
    }
  4. Given nn balls of some colors, where the ithi^{th} ball’s color is a[i]a[i], you need to find the minimum number of arrangements of these balls module 109+710^9 + 7 where you can perform an operation atmost once, in which you can choose all balls of one color and change their color to some other color.

    • 1n1051 \leq n \leq 10^5
    • 1a[i]n1 \leq a[i] \leq n
    Solution

    You need to use the simple formula for the number of arrangements of nn balls of kk colors, which is n!a[1]!a[2]!a[k]!\frac{n!}{a[1]! \cdot a[2]! \ldots a[k]!}. It is clear to minimise the value of this expression, we must combine the two largest colour groups into one. The time complexity of the solution is O(nlogn)O(n \log n) due to sorting and some addtional time is needed for the factorial calculation.

    1
    long long mod = 1e9 + 7;
    2
    3
    long long binPower(long long a, long long b)
    4
    {
    5
    long long res = 1;
    6
    while (b)
    7
    {
    8
    if (b & 1)
    9
    res = (res * a) % mod;
    10
    a = (a * a) % mod;
    11
    b >>= 1;
    12
    }
    13
    return res;
    14
    }
    15
    16
    int main()
    17
    {
    18
    int n, k;
    19
    cin >> n >> k;
    20
    21
    vector<long long> fac(n + 1);
    22
    fac[0] = 1;
    23
    for (int i = 1; i <= n; i++)
    24
    fac[i] = (fac[i - 1] * i) % mod;
    25
    26
    vector<int> arr(k);
    27
    for (int i = 0; i < k; i++)
    28
    cin >> arr[i];
    29
    sort(arr.begin(), arr.end(), greater<int>());
    30
    31
    if (k == 1)
    32
    {
    33
    cout << 1 << "\n";
    34
    return 0;
    35
    }
    36
    37
    arr[1] += arr[0];
    38
    long long ans = fac[n];
    39
    for (int i = 1; i < k; i++)
    40
    ans = (ans * binPower(fac[arr[i]], mod - 2)) % mod;
    41
    42
    cout << ans << "\n";
    43
    }
  5. Same question as Deutsche Bank: Question 11 & 22 from the Online Assessment Question section.

  6. Same question as Deutsche Bank: Question 22, 99 & 1717 from the Other Campus Questions section.

  7. Same question as HiLabs: Question 1414 from the Other Campus Questions section.

  8. You are given a number nn, which represents time. Starting from the origin, you can move in any of the fourth cardinal directions, but once you make a move, the next move that you make should be perpendicular to the previous move. What is the distinct number of coordinates reachable with this time?

    • 1n1031 \leq n \leq 10^3
    Solution

    Due to the small constraint on the value of nn, we can simply simulate the movement of the person and keep track of the coordinates that are reachable. The time complexity of the solution is O(n2)O(n^2) if we use a BFS to simulate all the possible moves.

    1
    int main()
    2
    {
    3
    int n;
    4
    cin >> n;
    5
    6
    // Y, X, DIR -> 0 for HOR, 1 for VER
    7
    int vis[2 * n + 1][2 * n + 1][2];
    8
    memset(vis, 0, sizeof(vis));
    9
    10
    queue<vector<int>> q;
    11
    q.push({n, n, 0});
    12
    q.push({n, n, 1});
    13
    vis[n][n][0] = 1;
    14
    vis[n][n][1] = 1;
    15
    16
    int dx[] = {0, 1, 0, -1};
    17
    int dy[] = {1, 0, -1, 0};
    18
    int ddir[] = {1, 0, 1, 0};
    19
    20
    int dis = 0;
    21
    while (!q.empty())
    22
    {
    23
    int sz = q.size();
    24
    dis++;
    25
    if (dis > n)
    26
    break;
    27
    28
    while (sz--)
    29
    {
    30
    auto t = q.front();
    31
    q.pop();
    32
    33
    int y = t[0], x = t[1], dir = t[2];
    34
    for (int k = 0; k < 4; k++)
    35
    {
    36
    int yn = y + dy[k], xn = x + dx[k], ndir = ddir[k];
    37
    if (ndir == dir)
    38
    continue;
    39
    if (!vis[yn][xn][ndir])
    40
    {
    41
    vis[yn][xn][ndir] = 1;
    42
    q.push({yn, xn, ndir});
    43
    }
    44
    }
    45
    }
    46
    }
    47
    48
    int cnt = 0;
    49
    for (int i = 0; i <= 2 * n; i++)
    50
    for (int j = 0; j <= 2 * n; j++)
    51
    cnt += max(vis[i][j][0], vis[i][j][1]);
    52
    cout << cnt << endl;
    53
    }
  9. You are given a graph of nn cities and mm edges between these cities. If two cities are connected, then they belong to the same kingdom. You are also given an array arrarr of length nn where arr[i]arr[i] denotes the number of people living in the group ii. You need to assign each group to exactly 11 unique city so that the sum of number of friendships across all the kingdoms is the maximum possible. A pair of people are said to be friends if they belong to the same kingdom. Output the maximum possible number of friendships.

  1. You are given a binary string of length nn. You need to count the number of substrings it has such that it has atleast xx bits set.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1xn1 \leq x \leq n
    Solution

    We can use a simple two pointer approach to count the number of substrings that have atleast xx bits set. The time complexity of the solution is O(n)O(n).

    1
    int main() {
    2
    int n, x;
    3
    cin >> n >> x;
    4
    5
    string s;
    6
    cin >> s;
    7
    8
    int cnt = s[0] == '1';
    9
    int j = 0;
    10
    11
    long long ans = 0;
    12
    for (int i = 0; i < n; i++) {
    13
    while (cnt < x && j + 1 < n) {
    14
    j++;
    15
    cnt += s[j] == '1';
    16
    }
    17
    18
    if (cnt < x)
    19
    break;
    20
    ans += n - j;
    21
    cnt -= s[i] == '1';
    22
    }
    23
    24
    cout << ans << endl;
    25
    }
  2. You are given two positive integers XX and YY without leading zeroes. You can perform an operation on these integers any number of times, in which you can delete a digit of the given number such that resulting number does not have leading zeroes: Let XX' and YY' be two numbers that were formed after performing operations on XX and YY respectively. You have to find the number of all the unique pairs of XX' and YY' whose XOR is zero.

    Two pairs of numbers (A,B)(A, B) and (C,D)(C, D) are considered different if and only if ACA \neq C and BDB \neq D.

    Constraints:

    • 1X,Y10121 \leq X, Y \leq 10^{12}
    • XX and YY do not have leading zeroes.
    Solution

    Two numbers XX and YY have XOR equal to 00 only and only if they are equal to each other. Thus the answer is nothing but the number of common subsequences of the two numbers when represented as string. We must be careful to exclude the strings with leading zeros. The complexity of the solution is (21212)(2^{12} \cdot 12) as we will be using a bitmask to generate the subsequences.

    1
    void addNumbers(string &s, set<long long> &pre) {
    2
    for (int mask = 1; mask < (1 << s.size()); mask++) {
    3
    string t;
    4
    for (int i = 0; i < s.size(); i++) {
    5
    if (mask & (1 << i))
    6
    t += s[i];
    7
    }
    8
    9
    if (t[0] == '0')
    10
    continue;
    11
    12
    long long v = stoll(t);
    13
    pre.insert(v);
    14
    }
    15
    }
    16
    17
    int main() {
    18
    long long a, b;
    19
    cin >> a >> b;
    20
    21
    string x = to_string(a), y = to_string(b);
    22
    23
    set<long long> s1, s2;
    24
    addNumbers(x, s1);
    25
    addNumbers(y, s2);
    26
    27
    long long ans = 0;
    28
    for (auto v : s1)
    29
    if (s2.count(v))
    30
    ans++;
    31
    32
    cout << ans << endl;
    33
    }
  3. You are given a tree of NN nodes and N1N - 1 edges rooted at node 11 with exactly one candy placed at each node. Let’s say the cost of the candy placed on the ithi^{th} node is A[i]A[i] and you have KK amount of money. Now, you will choose exactly one node (say, uu) and will start buying the candies placed on the path from node uu to the root until you run out of money, that is, first, you will buy the candy placed at node uu ,then the candy placed at the ancestor of uu, then it’s ancestor so on till you run out of money or you reach root node. Also, you cannot skip over a node without buying the candy placed on it. Calculate the the maximum number of candies you can buy in a given amount of money by choosing exactly one starting node.

    Constraints:

    • 1N1051 \leq N \leq 10^5
    • 1A[i]1091 \leq A[i] \leq 10^9
    • 1K10181 \leq K \leq 10^{18}
    Solution

    We will use binary lifting to solve this problem. For each node, we would calculate the 2jth{2^j}^{th} ancestor of the node and the money that we would need to spend to reach the ancestor. Then we can simply iterate over all the nodes and calculate the maximum number of candies that we can buy. The time complexity of the solution is O(NlogN)O(N \log N).

    1
    int main()
    2
    {
    3
    int n;
    4
    cin >> n;
    5
    6
    long long amt;
    7
    cin >> amt;
    8
    9
    vector<int> arr(n);
    10
    for (int i = 0; i < n; i++)
    11
    cin >> arr[i];
    12
    13
    vector<vector<int>> g(n);
    14
    for (int i = 0; i < n - 1; i++)
    15
    {
    16
    int u, v;
    17
    cin >> u >> v;
    18
    g[u - 1].push_back(v - 1);
    19
    g[v - 1].push_back(u - 1);
    20
    }
    21
    22
    int l = ceil(log2(n));
    23
    vector<vector<pair<int, long long>>> up(n, vector<pair<int, long long>>(l + 1));
    24
    25
    function<void(int, int)> dfs = [&](int u, int p) -> void
    26
    {
    27
    if (p == -1)
    28
    up[u][0] = {-1, 1e18};
    29
    else
    30
    up[u][0] = {p, arr[p]};
    31
    32
    for (int i = 1; i <= l; i++)
    33
    {
    34
    int v = up[u][i - 1].first;
    35
    long long c = up[u][i - 1].second;
    36
    if (v == -1)
    37
    up[u][i] = {-1, 1e18};
    38
    else
    39
    up[u][i] = {up[v][i - 1].first, c + up[v][i - 1].second};
    40
    }
    41
    42
    for (int v : g[u])
    43
    {
    44
    if (v == p)
    45
    continue;
    46
    dfs(v, u);
    47
    }
    48
    };
    49
    dfs(0, -1);
    50
    51
    int ans = 0;
    52
    for (int i = 0; i < n; i++)
    53
    {
    54
    if (arr[i] > amt)
    55
    continue;
    56
    57
    int u = i, cnt = 1;
    58
    long long left = amt - arr[i];
    59
    60
    for (int j = l; j >= 0; j--)
    61
    {
    62
    auto [v, c] = up[u][j];
    63
    if (v != -1 && c <= left)
    64
    {
    65
    left -= c;
    66
    u = v;
    67
    cnt += (1 << j);
    68
    }
    69
    }
    70
    ans = max(ans, cnt);
    71
    }
    72
    73
    cout << ans << endl;
    74
    }
  4. You are given a circular array with nn elements. In one operation, you can swap any two adjacent elements. What is the minumum number of operations you need to perform to make the first two elements of the array same? Return 1-1 is the same is never possible.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1a[i]1091 \leq a[i] \leq 10^9
    Solution

    We will iterate over all the elements, and count the moves needed to make them the first two elements. We will then take the minimum of all the moves. The time complexity of the solution is O(n)O(n).

    1
    int main() {
    2
    int n;
    3
    cin >> n;
    4
    5
    map<int, vector<int>> idx;
    6
    for (int i = 0; i < n; i++) {
    7
    int x;
    8
    cin >> x;
    9
    idx[x].push_back(i);
    10
    }
    11
    12
    int ans = 1e9;
    13
    for (auto &[_, v]: idx) {
    14
    int l = v.size();
    15
    if (l == 1)
    16
    continue;
    17
    18
    ans = min(ans, v[0] + abs(v[1] - 1));
    19
    ans = min(ans, n - v.back() + abs(v[0] - 1));
    20
    }
    21
    22
    if (ans == 1e9)
    23
    ans = -1;
    24
    cout << ans << endl;
    25
    }
  5. You are given an undirected graph that contains N+1N + 1 nodes and MM edges. These nodes are numbered from 00 to NN. Initially, you start at node 00. Each node except node 00 has a priority associated with it that is denoted by the array denoted as PP. You have to follow these commands to visit each noche in the path:

    1. You have to start at node 00 and move to the next unvisited node which directly connected to node 00 and having the highest priority.
    2. If the priority is the same for multiple nodes, then you have to select the nodes that have the minimum distance between them.
    3. After going to the next node, you have to again select a connected node that has the highest priority among the remaining unvisited nodes
    4. If there are no adjacent unvisited nodes at a point, then you have to traverse back to the previous node from where you came to the present node for the first time
    5. You cannot traverse the path once you reach the last unvisted node.

    If the distance between the node xx to node yy is dd, then the time elapsed to reach from one node to another is dd units. Determine the time required to reach at each node except node 00 for the first time. The given graph is a connected graph.

    Constraints:

    • 1N1051 \leq N \leq 10^5
    • 1M1051 \leq M \leq 10^5
    • 1P[i]1091 \leq P[i] \leq 10^9
  6. You are given the two arrays aa and bb of length nn and mm respectively. Consider the following points on the coordinate plane:

    • (a1,0),(a2,0)...,(an,0)(a_1,0), (a_2,0) ..., (a_n, 0)
    • (b1,1),(b2,1)...,(bm,1)(b_1, 1), (b_2, 1) ..., (b_m, 1)

    Find the area of the largest rectangle that can be constructed from the given points. If there is no rectangle possible then print 00.

    Constraints:

    • 1n,m1051 \leq n, m \leq 10^5
    • 1a[i],b[i]1091 \leq a[i], b[i] \leq 10^9
    Solution

    It is obvious that it is only possible to form a rectangle if there are atleast 22 points on the same line. We can iterate over all the points and store all the points that are common in aa and bb, and then take the minimum and maximum of the points to calculate the area of the rectangle. The time complexity of the solution is O(nlogn+mlogm)O(n \log n + m \log m).

    1
    int main() {
    2
    int n, m;
    3
    cin >> n >> m;
    4
    5
    vector<int> a(n), b(m);
    6
    for (int i = 0; i < n; i++)
    7
    cin >> a[i];
    8
    for (int i = 0; i < m; i++)
    9
    cin >> b[i];
    10
    11
    sort(a.begin(), a.end());
    12
    sort(b.begin(), b.end());
    13
    14
    vector<int> common;
    15
    int i = 0, j = 0;
    16
    while (i < n && j < m) {
    17
    if (a[i] == b[j])
    18
    common.push_back(a[i]);
    19
    if (a[i] < b[j])
    20
    i++;
    21
    else
    22
    j++;
    23
    }
    24
    25
    if (common.size() < 2)
    26
    cout << 0 << endl;
    27
    else
    28
    cout << common.back() - common[0] << endl;
    29
    }
  7. You need to implement the Least Frequently Used (LFU) cache with the capacity NN. You are also given QQ operations of the following type:

    1. (1,key,1)(1, key, -1): Get the value of the keykey from the cache. If the value does not exist in the cache return 1-1.
    2. (2,key,value)(2, key, value): Update the value of the keykey if present, or insert the keykey if not already present.

    When the cache reaches it’s capacity, it should invalidate and remove the least frequently used key before inserting a new item. For this problem, when there is a tie (two or more keys with the same frequency), smallest key should be removed. For each operation of type 11, print the required value.

    Solution

    Since we need to remove the key with the smallest value when the cache is full, we can use a set to store the keys in sorted order. We can use a map to store the frequency of the keys and a set to store the keys with the same frequency. The time complexity of the solution is O(QlogN)O(Q \log N).

    class LFU {
    int cap;
    map<int, int> kvMap;
    map<int, int> freqMap;
    set<pair<int, int>> freqSet;
    void increaseFreq(int key) {
    int freq = freqMap[key];
    freqSet.erase({freq, key});
    freqMap[key]++;
    freqSet.insert({freqMap[key], key});
    }
    public:
    LFU(int capacity) {
    cap = capacity;
    }
    int get(int key) {
    if (kvMap.find(key) == kvMap.end())
    return -1;
    increaseFreq(key);
    return kvMap[key];
    }
    void set(int key, int val) {
    if (kvMap.find(key) != keyMap.end()) {
    kvMap[key] = val;
    increaseFreq(key);
    return;
    }
    if (kvMap.size() == cap) {
    auto [toRem, _] = *freqSet.begin();
    kvMap.erase(toRem);
    freqMap.erase(toRem);
    freqSet.erase(freqSet.begin());
    }
    kvMap[key] = val;
    freqMap[key] = 1;
    freqSet.insert({1, key});
    }
    };
    int main() {
    int cap;
    cin >> cap;
    LFU lfu(cap);
    int q;
    cin >> q;
    while (q--) {
    int ty, key, val;
    cin >> ty >> key >> val;
    if (ty == 1)
    cout << lfu.get(key) << endl;
    else
    lfu.set(key, val);
    }
    }
  8. During your English exam, you are given a question to find whether a sentence is valid according to the defined rules. You need to create a basic sentence checker that takes in strings as input and determines whether they form valid sentences. You can consider a sentence valid if it conforms to the following rules:

    1. The sentence must start with a capital letter, followed by a lowercase letter, or a space.
    2. All other characters must be lowercase letters, separators (.:;) or terminal marks (.?!).
    3. There must be a single space between each word, where space is denoted by $.
    4. The sentence must end with a terminal mark immediately following a word.

    You are given an integer NN where NN denotes the length of the string sentence. You are given a string sentence that you need to validate. Print 11 if the string sentence is valid else print 00.

  9. Alice wanted to setup a chain of restaurants in a town. The town is represented as an XX axis on the number line. The town consists of NN houses, and the location of each house is known and given by array AA. She has to deliver food at each house location. She will set up KK restaurants in the town and appoint as many delivery boys as she wants at each restaurant. All delivery boys leave the restaurants together for food delivery for all the locations. She will choose KK locations in town to set up restaurants, such that all food packets get delivered in the minimum possible time. Determine the minimum time in which all food packets get delivered to each house in the town.

    • It takes one unit of time to travel one unit distance.
    • There is no delay in delivering the food packet, once the delivery boy has reached the delivery location.
    • There is no limit on food packets that can be delivered by a single delivery boy.
    Solution

    We will binary search on the minimum of the maximum distance that all the houses can have from any restaurants. The time complexity is Nlog(max(A))N \log(max(A)).

    1
    int main() {
    2
    int n, k;
    3
    cin >> n >> k;
    4
    5
    vector<int> arr(n);
    6
    for (int i = 0; i < n; i++)
    7
    cin >> arr[i];
    8
    sort(arr.begin(), arr.end());
    9
    10
    auto check = [&](int mx) -> bool {
    11
    int cnt = 0, lastRes = -1e9;
    12
    13
    for (int i = 0; i < n; i++) {
    14
    if (abs(lastRes - arr[i]) <= mx)
    15
    continue;
    16
    cnt++;
    17
    lastRes = arr[i] + mx;
    18
    }
    19
    20
    return cnt <= k;
    21
    };
    22
    23
    int l = 0, r = arr.back() - arr[0];
    24
    int ans = -1;
    25
    while (l <= r) {
    26
    int m = (l + r)/2;
    27
    if (check(m)) {
    28
    ans = m;
    29
    r = m - 1;
    30
    } else l = m + 1;
    31
    }
    32
    33
    cout << ans << "\n";
    34
    }

Probability Questions

  1. Patel is having a party for 100100 foreign delegates at his farmhouse. Out of the 100100 guests, 9090 can speak French, 8080 can speak German and 7575 can speak Dutch. Mr. Patel, as a diplomatic policy, starts giving a thank you note speech for all his guests which has phrases from all the three languages. At least, how many people would understand the full speech given by Mr. Patel?

  2. On a lazy Sunday afterrioon, Chandler thinks of challenging Joey for his love of pizzas. He comes up with a game where Chandler throws a dice and the number that appears on the dice would be the number of pizza slices Joey will have to eat, except when 66 appears. In that case, Joey has to eat 55 pizza slices and Chandler gets to throw the dice again. This may continue Indefinitely. What is the expected number of pizza slices Joey will eat?

  3. There is an array of size 2020, with numbers from 11-2020. A random permutation of these numbers is stored in the array. What is the expected number of local minimas in the array. (A point is called local minima if it is the lowest among its neighbours, with first and last index having only one neighbour)

  4. Mama’s Pizza Kitchen has a 5050 percent discount every Friday, Rohit has promised his friends for a treat on his new job’s first salary but will get his salary credited on the last business day of the month. What is the probability that Rohit would be able to avail the offer the day he receives his salary and takes his friends out on a treat to Mamma’s Pizza Kitchen?

  5. If Correlation(PQ)=0.5Correlation(PQ) = 0.5 and Correlation(QR)=0.5Correlation(QR) = 0.5, what is the maximum possible value of Correlation(PR)Correlation(PR)?

  6. You host a game where a person throws two dice. Person will get money according to dice rolls (d1d_1,d2d_2 being the numbers on respective dice throws). The payout will be equal to max(0,d1d230)max(0, d_1 \cdot d_2 - 30). What is the expected value of the game?

  7. You are given a box with 100100 balls (5050 yellow and 5050 red). You pick balls from the box one by one without replacements until all the balls are out. A yellow followed by a red or a red followed by a yellow is termed as “Flip”. Calculate the expected number of “Flip” if the balls are being picked at random.

  8. What are the two next terms in the sequences:

    1. 11,21,1211,11122111, 21, 1211, 111221
    2. 10,11,12,13,14,20,22,10110, 11, 12, 13, 14, 20, 22, 101
  9. Sum 2525 is to be broken down into a set of positive integers x1,x2,x3...,xkx_1, x_2, x_3 ..., x_k such that the product of x1x_1 to xkx_k is maximised. What is the maximum product possible?

  10. You are a trader considering a stock whose next price movement will be up or down with equal probability. Fortunately you have access to a binary signal predictive of the price change (observable ahead of time). The signal is 7575% accurate, conditional on the stock going up. There is a 0.750.75 probability that the signal says up and 0.250.25 probability that it says down. The reverse is true if stock goes down. You have access to many such signals, all with the same accuracy.

    Assume they are conditionally independent given the price movement (eg. conditional of the stock going up, there’s a 0.7520.75^2 probability that signals one and two both point up). Suppose you observe 1010 such signals and out of those 66 of them are pointing up, while 44 of them are pointing down. What is the probability that will go up?

  11. A bitwise XOR for all tile numbers in a list ll is calculated as: 11 if the number of times 11 appears in the bit is odd and 00 if the number of times 11 appears in the list is even. A function THOR(M,N)THOR(M,N) is defined as the XOR of all natural numbers between MM & NN, both MM and NN inclusive. What is the value of THOR(51,100)THOR(51,100)?

  12. There are 1010 socks Monica has with numbers 11 to 1010 on them. Out of those 55 socks are white and 55 are blue. She has numbered 55 white socks from 11 to 55 and blue socks from 66 to 1010. Joey, Chandler, Ross, Rachel and Phoebe come one by one and pick one blue and one white sock randomly. Score of every person is determined by the sum of the pair of socks they wear. What is the probability that the product of scores of those all five friends is divisible by 1111.

  13. What is the smallest nn such that n!n! has 100100 zeroes?

  14. There are 55 doors. Behind one of them is a Mercedes Benz and behind the other the key to the Mercedez. The remaining three doors are empty. Hrithik knows what is behind all the doors. He asks you to choose two doors. After you choose doors, he opens an empty door which is not chosen by you. Now he gives you a chance to either stick to your earller chosen doors or to switch to the other closed doors. You win the car if you choose doors having both a car and a key. Let pp be the probability of winning the car in the best case. What is 100p100 \cdot p?

  15. You are playing a game with your friend, in which you toss a fair coin. You win 11 point from your friend if the head comes, and if talis comes your friend wins 11 point from you (your score is 1-1). The game continues till either one of you reaches a total of 22 points (and the other one has 2-2 points). At this point the winner gets 1010 dollars from the loser.

    1. What is the expected value of this game?
    2. Now, assume you have an option to double the payoff (from 1010 to 2020) of the winner at any point of the game. You can use this option only once. What is the expected value of the new game?
  16. A country has only 22 denominations: 1313 and 1717. What is the highest integral amount that cannot be made using only these 22 denominations?

  17. What is the total number of 55 digit numbers such that the product of the digits of that number is divisible by 1010?

    • Case 11: Consider numbers whose product is 0 to be divisible by 10.
    • Case 22: Consider only non-zero digit numbers.
  18. There are 7070 people in a group, for any two members XX and YY there is a language that XX speaks but YY does not and there is a language that YY speaks but XX does not. What is the minimum number of distinct languages spoken by this group?

Online Assessment Questions

  1. There are aa string potions and bb weak potions. You need to prepare a mixture of cc potions, such that it atleast has 33 strong potions and 11 weak potions. What is the total number of ways to prepare the mixture?

    Constraints:

    • 1a,b,c301 \leq a, b, c \leq 30
  2. You are given a tree with nn vertices. Figure out the number of unordered pairs of distinct vertices such that the simple path between them has exactly 11 prime node lying on it.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    Solution
    #include <bits/stdc++.h>
    using namespace std;
    #define IOS \
    ios_base::sync_with_stdio(0); \
    cin.tie(0); \
    cout.tie(0)
    #define ll long long int
    #define vll vector<long long int>
    #define range(x, s, n) for (int x = s; x < n; ++x)
    void solution();
    int main()
    {
    IOS;
    int TEST_CASES;
    TEST_CASES = 1;
    while (TEST_CASES--)
    solution();
    return 0;
    }
    class DSU
    {
    public:
    vector<long long> p, sz, cnt;
    int n;
    DSU(int n)
    {
    this->n = n;
    p.assign(n, 0);
    range(i, 0, n) p[i] = i;
    sz.assign(n, 1);
    cnt.assign(n, 0);
    }
    int find(int v)
    {
    if (p[v] == v)
    return v;
    return p[v] = find(p[v]);
    }
    void join(int u, int v)
    {
    u = find(u), v = find(v);
    if (u == v)
    return;
    if (sz[u] < sz[v])
    swap(u, v);
    sz[u] += sz[v];
    cnt[u] += cnt[v];
    p[v] = u;
    }
    void incr(int v)
    {
    cnt[find(v)]++;
    }
    };
    void solution()
    {
    int n;
    cin >> n;
    vector<bool> isPrime(n + 1, 1);
    isPrime[0] = 0;
    isPrime[1] = 0;
    for (int i = 2; i * i <= n; i++)
    if (isPrime[i])
    for (int j = i * i; j <= n; j += i)
    isPrime[j] = 0;
    DSU dsu(n + 1);
    vector<vector<int>> g(n + 1);
    range(i, 0, n - 1)
    {
    int u, v;
    cin >> u >> v;
    if (!isPrime[u] && !isPrime[v])
    dsu.join(u, v);
    g[u].push_back(v);
    g[v].push_back(u);
    }
    long long ans = 0;
    range(i, 1, n + 1) if (isPrime[i])
    {
    ll tot = 0;
    vll v;
    for (int j : g[i])
    if (!isPrime[j])
    {
    v.push_back(dsu.sz[dsu.find(j)]);
    tot += v.back();
    }
    ans += tot;
    ll c = 0;
    for (ll x : v)
    c += x * (tot - x);
    ans += c / 2;
    }
    cout << ans << "\n";
    }
  3. You are given two arrays aa and bb of length nn. You need to select a subset of indices from 1..n1..n such that for any pair of indices i,ji, j, atleast one of the following conditions would hold true:

    • If ai<aja_i < a_j, then bi<bjb_i < b_j
    • If ai>aja_i > a_j, then bi>bjb_i > b_j
    • If ai=aja_i = a_j, then bibjb_i \neq b_j

    Find the length of maximum possible subset.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1a[i],b[i]1091 \leq a[i], b[i] \leq 10^9
  4. There are nn people, numbered from 11 to nn. You are also given an vector of pairs (i,j)(i, j) if two people ii and jj have an enemity. You need to fivide these people into two teams of equal size such that two people who are enemies are not on the same team. It is also guraunteed that each person has enemity with atmost 22 other people. Find the largest possible team size that can be made.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 0enemies1050 \leq |enemies| \leq 10^5
  5. You are given an array arrarr of integers also qq queries. For each query of the form (x,m)(x, m) you need to find the number of elements yy from the array arrarr such that the value 2(xy)xy2 \cdot (x | y) - x \oplus y is greater than or equal to mm. Here | is bitwise OR and \oplus is bitwise XOR.

    Constraints:

    • 1n1051 \leq n \leq 10^5
    • 1q1051 \leq q \leq 10^5
    • 1arr[i],x,m1091 \leq arr[i], x, m \leq 10^9