Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* Problem: Range Update Queries (CSES 1651)
* Link: https://cses.fi/problemset/task/1651/
* Difficulty: Easy (as per repo classification)
*
* Short Problem Statement:
* Given an array of N integers, process Q queries of two types:
* 1. Increase value in range [a, b] by u.
* 2. Find the current value at position k.
*
* Approach (Difference Array + Fenwick Tree):
* While a standard Difference Array allows O(1) updates, calculating a point value
* requires O(N) time (prefix sum), which is too slow for mixed queries (O(NQ)).
* * To solve this efficiently:
* 1. We use the concept of a Difference Array:
* - Update [L, R] by +X is equivalent to:
* diff[L] += X
* diff[R+1] -= X
* 2. We use a Fenwick Tree (Binary Indexed Tree) to maintain these difference updates.
* - The BIT allows us to perform the updates and calculate prefix sums in O(log N).
* 3. The value at index `k` is: Initial_Array[k] + Prefix_Sum_of_Diff(k).
*
* Time Complexity: O((N + Q) log N)
* Space Complexity: O(N)
*/

#include <iostream>
#include <vector>

using namespace std;

const int MAXN = 200005;
long long bit[MAXN];
int n, q;

// Update operation for Fenwick Tree (1-based indexing)
void update(int idx, long long val) {
for (; idx <= n; idx += idx & -idx) {
bit[idx] += val;
}
}

// Query prefix sum up to idx
long long query(int idx) {
long long sum = 0;
for (; idx > 0; idx -= idx & -idx) {
sum += bit[idx];
}
return sum;
}

void solve() {
cin >> n >> q;

vector<long long> initial_arr(n + 1);
for (int i = 1; i <= n; i++) {
cin >> initial_arr[i];
}

// Process queries
while (q--) {
int type;
cin >> type;

if (type == 1) {
// Range Update: 1 a b u
int a, b;
long long u;
cin >> a >> b >> u;
// Apply difference array logic using BIT
update(a, u);
update(b + 1, -u);
} else {
// Point Query: 2 k
int k;
cin >> k;
// Result is initial value + accumulated changes
cout << initial_arr[k] + query(k) << "\n";
}
}
}

int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
solve();
return 0;
}
109 changes: 109 additions & 0 deletions algos/range_queries/PrefixSum/soln/Krishna200608/Solution1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
====================================================
Problem: Reverse Sort (Codeforces 1605B)
====================================================

-------------------------
Short Problem Statement
-------------------------
You are given a binary string of length n.
In one operation, you may choose any subsequence of indices
and reverse the characters at those positions.
Determine whether the string can be sorted so that all 0s
come before all 1s. If possible, output the indices used
in at most one operation.

-------------------------
Approach (Prefix Sums + Difference Logic)
-------------------------
1. In a sorted binary string:
- All '0's appear first, then all '1's.
2. Let cnt0 be the total number of '0's in the string.
- Indices [0 ... cnt0-1] must be '0'
- Indices [cnt0 ... n-1] must be '1'
3. Build prefix sums:
- pref0[i] = number of '0's in s[0 ... i-1]
- pref1[i] = number of '1's in s[0 ... i-1]
4. Using cnt0, check each position:
- If s[i] != expected character, mark index (i+1)
5. If no mismatches exist → already sorted.
6. Otherwise, reversing all mismatched indices in ONE
operation always fixes the string.

-------------------------
Time & Space Complexity
-------------------------
Time Complexity: O(n) per test case
Space Complexity: O(n)

-------------------------
Example (Optional)
-------------------------
Input:
1
5
11001

Output:
1
4 1 2 4 5

-------------------------
Clean, Compiling C++ Code
-------------------------
*/

#include <bits/stdc++.h>
using namespace std;

void solve() {
int n;
cin >> n;
string s;
cin >> s;

// Prefix sums
vector<int> pref0(n + 1, 0), pref1(n + 1, 0);
for (int i = 0; i < n; i++) {
pref0[i + 1] = pref0[i] + (s[i] == '0');
pref1[i + 1] = pref1[i] + (s[i] == '1');
}

int cnt0 = pref0[n]; // total zeros

vector<int> indices;

// Identify mismatched positions
for (int i = 0; i < n; i++) {
char expected = (i < cnt0 ? '0' : '1');
if (s[i] != expected) {
indices.push_back(i + 1); // 1-based indexing
}
}

// Already sorted
if (indices.empty()) {
cout << 0 << '\n';
return;
}

// One reverse operation is sufficient
cout << 1 << '\n';
cout << indices.size();
for (int idx : indices) {
cout << " " << idx;
}
cout << '\n';
}

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);

int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
157 changes: 157 additions & 0 deletions algos/range_queries/PrefixSum/soln/Krishna200608/Solution2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
====================================================
Problem: Tracking Segments (Codeforces 1843E)
====================================================

-------------------------
Short Problem Statement
-------------------------
You are given:
- An array of length n, initially filled with 0s
- m segments [l, r]
- q update operations, where each operation turns one position into 1

After each update, more 1s are added (never removed).

A segment is called "beautiful" if it contains strictly more 1s than 0s.

Your task is to find the smallest k (1 ≤ k ≤ q) such that
after applying the first k updates, at least one segment becomes beautiful.
If no such k exists, output -1.

-------------------------
Approach (Binary Search + Prefix Sums)
-------------------------
Key Observations:
- Updates are monotonic: once a position becomes 1, it stays 1
- The condition "some segment becomes beautiful" is monotonic
(false → true, but never true → false)

Thus, we can binary search on k (number of applied updates).

For a fixed k:
1. Create an array arr[1..n], initially all 0
2. Apply the first k updates → set arr[queries[i]] = 1
3. Build prefix sum:
prefix[i] = number of 1s in arr[1..i]
4. For each segment [l, r]:
- ones = prefix[r] - prefix[l-1]
- length = r - l + 1
- zeros = length - ones
- if ones > zeros → segment is beautiful

If any segment is beautiful, k is valid.

-------------------------
Time & Space Complexity
-------------------------
Let:
- n = array size
- m = number of segments
- q = number of updates

Time Complexity:
- Each check: O(n + m)
- Binary search over q → O((n + m) * log q)

Space Complexity:
- O(n) for the array and prefix sums

-------------------------
Example (Optional)
-------------------------
Input:
1
5 2
1 3
2 5
3
1 2 3

Output:
2

Explanation:
After first 2 updates, segment [1,3] has more 1s than 0s.

-------------------------
Clean, Compiling C++ Code
-------------------------
*/

#include <bits/stdc++.h>
using namespace std;

bool check(int k, int n,
const vector<pair<int, int>>& segments,
const vector<int>& queries) {

vector<int> arr(n + 1, 0);

// Apply first k updates
for (int i = 0; i < k; i++) {
arr[queries[i]] = 1;
}

// Build prefix sum
vector<int> prefix(n + 1, 0);
for (int i = 1; i <= n; i++) {
prefix[i] = prefix[i - 1] + arr[i];
}

// Check all segments
for (auto [l, r] : segments) {
int ones = prefix[r] - prefix[l - 1];
int len = r - l + 1;
int zeros = len - ones;
if (ones > zeros) {
return true;
}
}

return false;
}

void solve() {
int n, m;
cin >> n >> m;

vector<pair<int, int>> segments(m);
for (int i = 0; i < m; i++) {
cin >> segments[i].first >> segments[i].second;
}

int q;
cin >> q;
vector<int> queries(q);
for (int i = 0; i < q; i++) {
cin >> queries[i];
}

int low = 1, high = q, ans = -1;

// Binary search for earliest valid k
while (low <= high) {
int mid = low + (high - low) / 2;
if (check(mid, n, segments, queries)) {
ans = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}

cout << ans << '\n';
}

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);

int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}