বাইনারি সূচকযুক্ত গাছগুলির সাথে রেঞ্জ আপডেট + রেঞ্জের ক্যোয়ারী


10

আমি বোঝার চেষ্টা করছি যে বাইনারি সূচকযুক্ত গাছগুলি (ফেনউইক ট্রি) কীভাবে পরিসীমা অনুসন্ধান এবং ব্যাপ্তি আপডেট উভয়ই পরিচালনা করতে পারে।

আমি নিম্নলিখিত উত্সগুলি পেয়েছি:

http://kartikkukreja.wordpress.com/2013/12/02/range-updates-with-bit-fenwick-tree/ http://programmingcontests.quora.com/ টিউটোরিয়াল- রেঞ্জ- Updates-in- Fenwick- ট্রি পোস্ট : //apps.topcoder.com/forums/ মডিউল = থ্রেড & threadID = 756271 & শুরু = 0 & MC = 4 # 1579597

তবে এগুলি সব পড়ার পরেও আমি বুঝতে পারি না দ্বিতীয় বাইনারি সূচকযুক্ত গাছের উদ্দেশ্য কী বা এটি কী করে।

কেউ দয়া করে আমাকে ব্যাখ্যা করতে পারেন কীভাবে বাইনারি সূচকযুক্ত গাছগুলি এগুলি পরিচালনা করতে পরিবর্তন করা হয়?

উত্তর:


9

ধরুন আপনার খালি অ্যারে ছিল:

0  0  0  0  0  0  0  0  0  0  (array)
0  0  0  0  0  0  0  0  0  0  (cumulative sums)

এবং আপনি +5 থেকে [3.7] এর একটি পরিসীমা আপডেট করতে চেয়েছিলেন:

0  0  0  5  5  5  5  5  0  0  (array)
0  0  0  5 10 15 20 25 25 25  (desired cumulative sums)

আপনি কীভাবে 2 বাইনারি সূচকযুক্ত গাছ ব্যবহার করে কাঙ্ক্ষিত ক্রমসংখ্যাটি সঞ্চয় করতে পারেন?

কৌশলটি হ'ল দুটি বাইনারি সূচকযুক্ত গাছ, বিআইটি 1 এবং বিআইটি 2 ব্যবহার করা, যেখানে তাদের সামগ্রীর থেকে সংযোজিত যোগফল গণনা করা হয়। এই উদাহরণে, আমরা দুটি গাছের মধ্যে যা সঞ্চয় করতাম তা এখানে:

0   0   0   5   5   5   5   5   0   0  (BIT1)
0   0   0  10  10  10  10  10 -25 -25  (BIT2)

এটির জন্য sum[i], আপনি এটি গণনা করুন:

sum[i] = BIT1[i] * i - BIT2[i]

উদাহরণ স্বরূপ:

sum[2] = 0*2 - 0 = 0
sum[3] = 5*3 - 10 = 5
sum[4] = 5*4 - 10 = 10
...
sum[7] = 5*7 - 10 = 25
sum[8] = 0*8 - (-25) = 25
sum[9] = 0*9 - (-25) = 25

পূর্ববর্তী পরিসরের আপডেটের জন্য কাঙ্ক্ষিত বিআইটি 1 এবং বিআইটি 2 মান অর্জন করতে আমরা 3 টি ব্যাপ্তি আপডেট করি:

  • বিআইটি 1 এর জন্য আমাদের সূচকগুলির 3.5 থেকে +5 এর একটি পরিসীমা আপডেট করতে হবে।

  • বিআইটি 2 এর জন্য আমাদের সূচকগুলির 3.10 থেকে + 10 এর একটি পরিসীমা আপডেট করতে হবে।

  • বিআইটি 2 এর জন্য আমাদের সূচি 8 -9 এর 25-এর পরিসীমা আপডেট করতে হবে।

এখন আরও একটি রূপান্তর করা যাক। বিআইটি 1 এবং বিআইটি 2 এর জন্য উপরের দেখানো মানগুলি সংরক্ষণ করার পরিবর্তে আমরা আসলে তাদের সংখ্যার যোগফলগুলি সঞ্চয় করি। এটি আমাদের সম্মিলিত অঙ্কের 4 টি আপডেট করে 3 টি রেঞ্জের আপডেটগুলি করতে দেয়:

BIT1sum[3] += 5
BIT1sum[8] -= 5
BIT2sum[3] += 10
BIT2sum[8] -= 35

সাধারণভাবে, একটি সীমাতে v মান যোগ করার আলগোরিদিম [i..j] হ'ল:

BIT1sum[i]   += v
BIT1sum[j+1] -= v
BIT2sum[i]   += v * (i-1)
BIT2sum[j+1] -= v * j

যেখানে + = এবং - = বাক্য গঠনটি কেবলমাত্র সেই সূচকটিতে ধনাত্মক বা নেতিবাচক মান সহ বিআইটি সংশ্লেষক সমষ্টি ডেটা স্ট্রাকচার আপডেট করে। নোট করুন যে আপনি যখন কোনও সূচকে বিআইটি সংযোজিত যোগফলটি আপডেট করেন তখন তা সূচকটির ডানদিকে সমস্ত সূচককে স্পষ্টতই প্রভাবিত করে। উদাহরণ স্বরূপ:

0 0 0 0 0 0 0 0 0 0 (original)

BITsum[3] += 5

0 0 0 5 5 5 5 5 5 5 (after updating [3])

BITsum[8] -= 5

0 0 0 5 5 5 5 5 0 0 (after updating [8])

ফেনউইক ট্রি একটি বাইনারি গাছে অঙ্কের সঞ্চয় করে। উপরে কোনও ফেনউইক ট্রিতে উপরে প্রদর্শিত আপডেটগুলি করা সহজO(logn) সময়।


বিআইটি 2 তৈরির এবং তারপরে আপনার প্রাথমিক প্রেরণাটি কী ছিল sum[i] = BIT1[i] * i - BIT2[i]? এটি কাজ করে বলে মনে হচ্ছে তবে এটি নির্বিচারে মনে হচ্ছে ... কী অন্তর্দৃষ্টি আপনাকে এখানে আসতে দেয়?
1110101001

3
আচ্ছা আমি এই অ্যালগরিদম আবিষ্কার করেনি। আমি যেমন পড়েছি ঠিক তেমন পড়েছি। তবে একটি বিষয় লক্ষণীয় যে আপনি যখন একটি পরিসীমা আপডেট যুক্ত করবেন তখন আপনার সংখ্যার যোগফলগুলি ক্রমবর্ধমান ক্রম হয় (5, 10, 15, 20, ...)। বিআইটিগুলি এর মতো ক্রমবর্ধমান ক্রমগুলি সঞ্চয় করে না। তবে আপনি যদি বিআইটি-তে একটি ধ্রুবক (5) সঞ্চয় করে থাকেন এবং সূচক দ্বারা বিআইটি মানকে গুণিত করেন তবে আপনি যা চান তার মতো ক্রমবর্ধমান ক্রম পাবেন get তবে আপনাকে ক্রমের শুরু এবং শেষ ঠিক করতে হবে fix দ্বিতীয় গাছের জন্য এটিই।
জেএস 1

, আমি বলব আপনি আসলে বিপরীত করছ, অর্থাত সংরক্ষণকারী - সমগ্র উপর গুড, কিন্তু আমি এটা বিভ্রান্তিকর আপনি লিখেছিলেন, "এর পরিবর্তে মান BIT1 এবং BIT2 জন্য উপরে দেখানো জমা করার, আমরা আসলে তাদের ক্রমসঞ্চিত অঙ্কের সংরক্ষণ" খুঁজে বদ্বীপ
j_random_hacker
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.