কম্পিউটার টিউটোরিয়াল

C++-এ দেওয়া রেঞ্জের জন্য সর্বোচ্চ প্রিফিক্স-সাম


সমস্যা বিবরণ

n সংখ্যক ইন্টিজারের একটি অ্যারে এবং q সংখ্যক কোয়েরি দেওয়া আছে, প্রতিটি কোয়েরিতে l থেকে r পর্যন্ত একটি রেঞ্জ থাকে। l – r রেঞ্জের জন্য সর্বোচ্চ প্রিফিক্স-সাম বের করতে হবে।

উদাহরণ

ইনপুট অ্যারে arr[] = {-1, 2, 3, -5} এবং কোয়েরি = 2 এবং রেঞ্জগুলো: l = 0, r = 3 l = 1, r = 3 তবে আউটপুট হবে 4 এবং 5।
  • ১ম কোয়েরির রেঞ্জ (0, 3) এ [-1, 2, 3, -5] আছে, যেহেতু এটি প্রিফিক্স, তাই আমাদের -1 থেকে শুরু করতে হবে। অতএব, সর্বোচ্চ প্রিফিক্স সাম হবে -1 + 2 + 3 = 4
  • ২য় কোয়েরির রেঞ্জ (1, 3) এ [2, 3, -5] আছে, যেহেতু এটি প্রিফিক্স, তাই আমাদের 2 থেকে শুরু করতে হবে। অতএব, সর্বোচ্চ প্রিফিক্স সাম হবে 2 + 3 = 5

এল्गরিদম

  • একটি সেগমেন্ট ট্রি বিল্ড করুন যেখানে প্রতিটি নোড দুটি মান সংরক্ষণ করবে: sum এবং prefix_sum, এবং এর ওপর রেঞ্জ কোয়েরি করুন সর্বোচ্চ প্রিফিক্স সাম বের করার জন্য।
  • সর্বোচ্চ প্রিফিক্স সাম বের করার জন্য দুটি জিনিস প্রয়োজন: একটি হলো যোগফল এবং অন্যটি প্রিফিক্স সাম।
  • মার্জিং দুটি জিনিস রিটার্ন করবে: রেঞ্জগুলোর যোগফল এবং প্রিফিক্স সাম যেটি সংরক্ষণ করবে max(prefix.left, prefix.sum + prefix.right) সেগমেন্ট ট্রিতে।
  • যেকোনো দুটি রেঞ্জ কম্বাইন করার জন্য সর্বোচ্চ প্রিফিক্স সাম হয় বাম পক্ষের প্রিফিক্স সাম হবে অথবা বাম পক্ষের যোগফল + ডান পক্ষের প্রিফিক্স সাম, যেটি সর্বোচ্চ সেটি বিবেচনা করা হবে।

উদাহরণ

#include <bits/stdc++.h> using namespace std; typedef struct node {    int sum;    int prefix; } node; node tree[4 * 10000]; void build(int *arr, int idx, int start, int end) {    if (start == end) {       tree[idx].sum = arr[start];       tree[idx].prefix = arr[start];    } else {       int mid = (start + end) / 2;       build(arr, 2 * idx + 1, start, mid);       build(arr, 2 * idx + 2, mid + 1, end);       tree[idx].sum = tree[2 * idx + 1].sum + tree[2 *       idx + 2].sum;       tree[idx].prefix = max(tree[2 * idx + 1].prefix,       tree[2 * idx + 1].sum + tree[2 * idx + 2].prefix);    } } node query(int idx, int start, int end, int l, int r) {    node result;    result.sum = result.prefix = -1;    if (start > r || end < l) {       return result;    }    if (start >= l && end <= r) {       return tree[idx];    }    int mid = (start + end) / 2;    if (l > mid) {       return query(2 * idx + 2, mid + 1, end, l, r);    }    if (r <= mid) {       return query(2 * idx + 1, start, mid, l, r);    }    node left = query(2 * idx + 1, start, mid, l, r);    node right = query(2 * idx + 2, mid + 1, end, l, r);    result.sum = left.sum + right.sum;    result.prefix = max(left.prefix, left.sum + right.prefix);    return result; } int main() {    int arr[] = { -2, -3, 4, -1, -2, 1, 5, -3 };    int n = sizeof(arr) / sizeof(arr[0]);    build(arr, 0, 0, n - 1);    cout << "Result = " << query(0, 0, n - 1, 3, 5).prefix    << endl;    return 0; }

আউটপুট

যখন আপনি উপরের প্রোগ্রামটি কম্পাইল এবং এক্সিকিউট করবেন। এটি নিচের আউটপুট জেনারেট করবে −

Result = -1

  1. C++-এ ম্যাট্রিক্সে সর্বোচ্চ পাথ সাম

  2. C++-এ ত্রিভুজে সর্বোচ্চ পথ যোগফল

  3. C++-এ দেওয়া রেঞ্জ থেকে সর্বোচ্চ বিটওয়াইজ AND যুগল

  4. C++-এ রেঞ্জ সম কোয়েরি আপডেট ছাড়া (Range Sum Queries Without Updates)