0% found this document useful (0 votes)
57 views14 pages

New Approcah

The document provides various algorithms and data structures including Difference Arrays for efficient range updates, Modulo Power Calculation, Multisets, and Weighted Medians. It also covers the Sieve of Eratosthenes for generating prime numbers and techniques for counting subarrays with specific bitwise properties. Each section includes definitions, key operations, examples, and C++ implementations where applicable.

Uploaded by

Yash Mathuria
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
57 views14 pages

New Approcah

The document provides various algorithms and data structures including Difference Arrays for efficient range updates, Modulo Power Calculation, Multisets, and Weighted Medians. It also covers the Sieve of Eratosthenes for generating prime numbers and techniques for counting subarrays with specific bitwise properties. Each section includes definitions, key operations, examples, and C++ implementations where applicable.

Uploaded by

Yash Mathuria
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 14

[1]📘 Difference Array for Efficient Range Updates

🔍 Definition

A Difference Array is a technique used to perform multiple range update operations on an array efficiently
in O(1) time per update.

Given an array arr[0..n-1], its difference array d is defined as:

 d[0] = arr[0]

 d[i] = arr[i] - arr[i-1] for 1 <= i < n

⚙️Key Operations

✅ Initialization (initDiffArray)

d[0] = arr[0]

for i from 1 to n-1:

d[i] = arr[i] - arr[i-1]

✅ Range Update in O(1) (update)

To apply +x to all elements in the range [l, r]:

d[l] += x

d[r + 1] -= x

✅ Construct Final Array (printArray)

To get the updated array from the difference array:

arr[0] = d[0]

for i from 1 to n-1:

arr[i] = arr[i-1] + d[i]

🧮 Example

Initial Array: arr = [2, 5, 7, 9, 6]


Difference Array: d = [2, 3, 2, 2, -3]

Apply Update: update(1, 3, 4)


→ d = [2, 7, 2, 2, -7]

Rebuild Array:
arr = [2, 9, 11, 13, 6]

💻 C++ Implementation

vector<int> initDiffArray(vector<int> &arr) {

int n = arr.size();
vector<int> d(n + 1, 0);

d[0] = arr[0];

for (int i = 1; i < n; i++) {

d[i] = arr[i] - arr[i - 1];

return d;

void update(vector<int> &d, int l, int r, int x) {

d[l] += x;

d[r + 1] -= x;

void printArray(vector<int> &arr, vector<int> &d) {

for (int i = 0; i < arr.size(); i++) {

if (i == 0)

arr[i] = d[i];

else

arr[i] = d[i] + arr[i - 1];

cout << arr[i] << " ";

cout << endl;

🧾 Time & Space Complexity

 update(l, r, x): O(1)

 printArray(): O(n)

 Space: O(n) for the difference array

https://leetcode.com/problems/zero-array-transformation-i/description/

[2] Modulo Power Calculation

long long modulopower(long long n){

if(n==1){

return 2;

if(n==0){
return 1;

if(n&1){

return (2LL * modulopower(n / 2) % MOD * modulopower(n / 2) % MOD) % MOD;

else{

return (1LL * modulopower(n / 2) % MOD * modulopower(n / 2) % MOD) % MOD;

[3] Multiset

-Basic Syntax
multiset<int> ms;

-Insertion
ms.insert(10); // Inserts 10

ms.insert(10); // Duplicates allowed

-Iteration
for (int x : ms)

cout << x << " ";

for (auto it = ms.begin(); it != ms.end(); ++it)

cout << *it << " ";

-Deletion
ms.erase(ms.find(10)); // Deletes one occurrence
ms.erase(10); // Deletes ALL occurrences

-Search
auto it = ms.find(10);

if (it != ms.end()) {

cout << "Found";

-Count Duplicates
int c = ms.count(10); // Number of times 10 appears

-Bounds
ms.lower_bound(x); // First element >= x
ms.upper_bound(x); // First element > x

-Size & Emptiness


ms.size(); // Total number of elements

ms.empty(); // Returns true if empty

-Clear All Elements


ms.clear(); // Empties the multiset

-Reverse Iteration
for (auto it = ms.rbegin(); it != ms.rend(); ++it)

cout << *it << " ";

-Initialize with Elements


multiset<int> ms = {5, 1, 3, 3, 7};

-Custom Comparator (Descending Order)


multiset<int, greater<int>> ms;

-Example Use Case: Ticket Problem


multiset<int> prices = {5, 3, 7, 8, 5};

int max_price = 6;

auto it = prices.upper_bound(max_price);

if (it == prices.begin()) cout << -1;


else {

--it;

cout <<

*it;prices.erase(it

);

-Tips
Prefer multiset when you need:

- Duplicates allowed

- Sorted elements

- Logarithmic insert/delete/search

[4] Weighted Median

If the cost for all element is the same, then the minimum cost is when

all numbers converge at the median.

Since the cost is not the same, we need to find a weighted median.

To find a weighted median, we sort elements, "repeating" each element

based on its weight.

For [1,3,5,2], [2,3,1,4] case, the repeated array looks like this (median

is in bold): [1,1,2,2,2,2,3,3,3,5].

We do not need to actually generate that repeated array, we can just

simulate it.

We find the total weight (10), aggregate the current weight going from

one side, and stop when current >= total / 2.

📌 Use Cases

 Minimize total weighted absolute deviation:

minimize ∑i∣x−ai∣⋅wi\text{minimize } \sum_{i} |x - a_i| \cdot

w_iminimize i∑∣x−ai∣⋅wi

 Problems like:

o Min-cost to make all elements equal with weights.


o Clustering, statistics, and resource allocation.

⚙️ Steps to Compute Weighted Median

1. Input: Array of pairs (value, weight) → vector<pair<long long, long

long>>.

2. Sort array by value.

3. Compute total weight W.

4. Traverse and accumulate weights until ≥ W / 2.

5. The current value is the weighted median.

🧪 Example

cpp

CopyEdit

values: [1, 3, 6]

weights: [2, 4, 3]

total weight = 9

Cumulative weights:

1 → 2

3 → 6 (>= 4.5) → weighted median = 3

📎 C++ Snippet

long long weighted_median(vector<pair<long long, long long>>& arr) {

sort(arr.begin(), arr.end()); // sort by value

long long total_weight = 0;

for (auto& p : arr) total_weight += p.second;

long long cumulative = 0;

for (auto& p : arr) {

cumulative += p.second;

if (cumulative >= (total_weight + 1) / 2) {

return p.first; // weighted median

}
}

return -1; // should not happen

🕒 Time Complexity

 O(n log n) – due to sorting.

 O(n) – for cumulative sum.

[5]a&-1=a;

[6] https://www.geeksforgeeks.org/program-nth-catalan-number/

[7] Lis using binary search

vector<int> lis;

for (int x : arr) {

auto it = lower_bound(lis.begin(), lis.end(), x);

if (it == lis.end()) lis.push_back(x);

else *it = x;

}
}

[8]

Given an array of integers nums and an integer k, return the number of subarrays of nums where
the bitwise AND of the elements of the subarray equals k.

class Solution
{
public:
long long countSubarrays(vector<int> &nums, int k)
{
return atLeastK(nums, k) - atLeastK(nums, k +1);
}
long long atLeastK(vector<int>& nums, int k){
long long ans = 0;
vector<int> temp(32, 0);

int l = 0;
for (int r = 0; r < nums.size(); r++)
{
for (int i = 0; i < 32; i++)
{
if ((1 << i) & nums[r])
{
temp[i]++;
}
}

while ((r - l + 1) > 0 && calc(temp, r - l + 1) < k)


{
for (int i = 0; i < 32; i++)
{
if ((1 << i) & nums[l])
{
temp[i]--;
}
}
l++;
}
ans += (r - l + 1);
}

return ans;
}
//function to calculate the AND from frequency vector
int calc(vector<int>& temp, int w){
int ans = 0;
for (int i = 0; i < 32;i++){
if(temp[i]==w)
ans += (1 << i);
}

return ans;
}
};

Here we are storing freq of each bit when we want to shrink the
window we simply convert our end ouput for window by considering two
cases
1. If freq of bit is==w than it wil be 1 for our result bit
2. If freq of bit is not equal to w than it will be 0 for our
result bit

[8]ReRooting in Tree is used when you already find value corresponding to root node and you want
to find values corresponding to other node in o(n) tc than we used this technique

https://leetcode.com/problems/sum-of-distances-in-tree/

class Solution {
public:
int dfs(vector<vector<int>>&adj,vector<int>&count,int
curr_node,int& root,int parent,int depth){
int total_node=1;
root+=depth;
for(auto it:adj[curr_node]){
if(it==parent)continue;
total_node+=dfs(adj,count,it,root,curr_node,depth+1);
}
count[curr_node]=total_node;
return total_node;
}
void
DFS(vector<vector<int>>&adj,vector<int>&count,vector<int>&result,
int curr_node,int parent){

for(auto it:adj[curr_node]){
if(it==parent)continue;
result[it]=result[curr_node]-(count[it])+
(count.size()-count[it]);
DFS(adj,count,result,it,curr_node);

}
}
vector<int> sumOfDistancesInTree(int n, vector<vector<int>>&
edges) {
vector<int>count(n,0);
vector<int>result(n,0);
vector<vector<int>>adj(n);
for(auto edge:edges){
int u=edge[0];
int v=edge[1];
adj[u].push_back(v);
adj[v].push_back(u);
}
int root=0;
dfs(adj,count,0,root,-1,0);
result[0]=root;
DFS(adj,count,result,0,-1);
return result;

}
};

The Formula:

result[child] = result[parent] - count[child] + (n - count[child])

Why this works:

 When moving root from parent to child:


o All nodes in child's subtree get closer by 1 → decrease total sum by
count[child]
o All other nodes get farther by 1 → increase total sum by n - count[child]

[9]

🧠 What is the Sieve of Eratosthenes?


The Sieve of Eratosthenes is a method to generate all prime numbers up to a given number
n using the idea of eliminating multiples of each prime number starting from 2.

It is based on the fact that:

Every composite number has a prime factor less than or equal to its square root.

🪜 Step-by-step Explanation
Let’s say we want to find all prime numbers from 1 to n = 30.

Step 1: Create a boolean array

 Create a boolean array isPrime[0...n] and initialize all values to true.


 Set isPrime[0] = false and isPrime[1] = false because 0 and 1 are not prime.

text
CopyEdit
Index: 0 1 2 3 4 5 6 7 8 9 10 ...
isPrime: [ F, F, T, T, T, T, T, T, T, T, T ... ]

Step 2: Start with the first prime number (2)

For every number p from 2 to √n:

 If isPrime[p] == true, mark all multiples of p (starting from p*p) as false.

Why start from p*p?

Because all smaller multiples (like 2p, 3p, ...) will already have been marked by smaller
primes.

Step 3: Mark multiples

Let’s apply it step-by-step:

p = 2:

Mark 4, 6, 8, 10, ..., 30 as not prime.

p = 3:

Mark 9, 12, 15, ..., 30 as not prime.


p = 4:

Already marked as not prime, so skip.

p = 5:

Mark 25, 30 as not prime.

Now stop — because p*p = 6*6 = 36 > 30.

Step 4: Collect remaining primes

All numbers i such that isPrime[i] == true are primes.

text
CopyEdit
Result: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29

🧮 Time and Space Complexity


Aspect Value
Time Complexity O(n log log n)
Space Complexity O(n)

It is much faster than checking each number one by one for primality.

✅ C++ Implementation
vector<bool> sieve(int n) {
vector<bool> isPrime(n + 1, true);
isPrime[0] = isPrime[1] = false;

for (int p = 2; p * p <= n; p++) {


if (isPrime[p]) {
for (int i = p * p; i <= n; i += p) {
isPrime[i] = false;
}
}
}

return isPrime; // true => prime, false => not prime


}

🧑‍🏫 Summary
 Simple yet efficient algorithm for generating primes.
 Uses the principle of eliminating multiples.
 Extremely useful in competitive programming and number theory problems.

[10] In string question try to find FIFO or LIFO property if nothing works

You might also like