حسنی و نفر از دوستانش دور یک دایره نشستند و شروع به انجام بازی اتلمتل توله میکنند. شیوه انجام بازی این جوری هست که حسنی به عنوان نفر اول میگوید "سلام!". بعد از آن در هر مرحله نفر تا جلوتر نفر قبلی میگوید "سلام!". این روال ادامه دارد تا دوباره نوبت حسنی شود و آن موقع بازی تموم میشود.
حالا حسنی میخواهد بداند که این بازی چند مرحله طول میکشد و از آنجا که خیلی سرگرم بازی شده، از شما میخواهد تا جواب را به او بگویید.
در خط اول ورودی و آمده است.
در تنها خط خروجی تعداد مراحلی را که طول میکشد تا دوباره نوبت حسنی شود را چاپ کنید.
اگر افراد دور دایره را از تا شمارهگذاری کنیم به طوری که حسنی شماره یک را بگیرد طبق چنین روندی دوباره نوبت حسنی میشود:
در این حالت افرادی که سلام میکنند چنین شمارههایی را دارند:
در این حالت نفر تا بعدی حسنی خود حسنی است!
سعی کنید روند بازی را به صورت ساده، جوری که بتوانید کد آن را بزنید، در بیاورید.
برای مثال در سوال آمده است "تا زمانی که نوبت دوباره به حسنی نرسیدهاست، بازی ادامه دارد." که این همان حلقه است. (با این لینک میتوانید بیشتر با حلقه آشنا شوید.)
فرض کنید دو متغیر cnt و cur دارید که در هر مرحله cnt برابر تعداد مراحل تا الان است و cur برابر اینکه اخرین نفری که گفت "سلام" چه کسی است.
برای مثالها مراحل را اجرا کنید و مقدار cur و cnt را در هر مرحله یادداشت کنید.
فرض کنید که افراد را از ۰ تا شمارهگذاری کردیم و حسنی شماره ۰ است.
مثلا برای ورودی نمونه ۲ که و است به این شکل مقدارهای متغیر بعد از هر مرحله تغییر میکند.
cnt | cur |
---|---|
۱ | ۰ |
۲ | ۲ |
۳ | ۴ |
و بعد از مرحله ۳ دوباره حسنی را میبینیم و بازی تمام میشود.
قسمت اصلی الگوریتم، یعنی شبیهسازی کردن بازی، از یک حلقه تشکیل شده است و دو متغیر cnt و curکه حلقه تا زمانی که بازی تمام نشده است، اجرا میشود.
شبه کد الگوریتم:
منظور از دستور break
این است که از حلقه while
بیرون بیاید و منظور از while true
یعنی تا زمانی که به دستور break
نرسیده است، حلقه را تکرار کند و منظور از assign 0 to *cnt*
این است که مقدار متغیر cnt
را برابر صفر بکن.
میتوانید مشاهده کنید که بعد هر مرحله cnt یک واحد زیاد میشود و cur باید برابر k-امین نفر جلو باشد. در صورتی که افراد را به ترتیب از 0 تا شماره گذاری کنید و حسنی 0 باشد. بعد هر مرحله cur به علاوه k میشود و سپس به پیمانه n باقی مانده گرفته میشود.
میتوانید شعر زیر را نخوانید و تاثیری در فهم سوال ندارد.
توی ده شلمرود
حسنی تک و تنها بود
حسنی نگو بلا بگو
تنبل تنبلها بگو
موی بلند، روی سیاه
ناخن دراز، واه و واه و واه
نه فلفی، نه قلقلی
نه مرغ زرد کاکلی
هیچکس باهاش رفیق نبود
تنها روی سه پایه، نشسته بود تو سایه
باباش میگفت: حسنی میای بریم حموم؟
«نه نمیام، نه نمیام»
سرت رو میخوای اصلاح کنی؟
«نه نمیخوام، نه نمیخوام»
کره الاغ کدخدا
یورتمه میرفت تو کوچهها
«الاغه چرا یورتمه میری؟»
«دارم میرم بار ببرم
دیرم شده عجله دارم»
«الاغ خوب و نازنین
سر در هوا سم بر زمین
یالت بلند و پرمو
دمت مثال جارو
یک کمی به من سواری میدی؟»
«نه که نمیدم»
«چرا نمیدی؟»
«واسه این که من تمیزم
پیش همه عزیزم اما تو چی؟
موی بلند، روی سیاه
ناخن دراز، واه و واه و واه!»
غازه پرید تو استخر
«تو اردکی یا غازی؟»
«من غاز خوش زبانم»
«میای بریم به بازی؟»
«نه جانم»
«چرا نمیای؟»
«واسه این که من
صبح تا غروب
میون آب، کنار جو
مشغول کار و شستشو
اما تو چی؟
موی بلند، روی سیاه
ناخن دراز، واه و واه و واه»
در وا شد و یه جوجه
دوید و اومد تو کوچه
جیکجیککنان
گردشزنان
اومد و اومد پیش حسنی
«جوجه کوچولو
کوچول موچولو
میای با من بازی کنی؟»
مادرش اومد «قدقدقدا
برو خونتون تو رو به خدا
جوجهی ریزه میزه
ببین چقد تمیزه؟
اما تو چی؟
موی بلند، روی سیاه
ناخن دراز، واه و واه و واه»
حسنی با چشم گریون
پا شد و اومد تو میدون
«آی فلفلی، آی قلقلی
میاین با من بازی کنین؟»
«نه که نمیایم»
«چرا نمیاین؟»
فلفلی گفت:
من و داداشم و بابام و عموم
هفتهای دو بار میریم حموم
اما تو چی؟
قلقلی گفت: نگاش کنین
موی بلند، روی سیاه
ناخن دراز، واه و واه و واه
حسنی دویید پیش باباش
«حسنی میای بریم حموم؟»
«میام، میام»
«سرتو میخوای اصلاح کنی؟»
«میخوام، میخوام»
حسنی نگو یه دسته گل
تر و تمیز و تپل مپل
الاغ و خروس و جوجه غاز و ببعی
با فلفلی با قلقلی با مرغ زرد کاکلی
حلقه زدن دور حسن
الاغه میگفت:
اگر کاری نداری
بریم الاغ سواری
خروسه میگفت:
قوقولی قوقو، قوقولی قوقو
هر چی میخوای، فوری بگو
مرغه میگفت:
حسنی برو تو کوچه
بازی بکن با جوجه
غازه میگفت:
حسنی بیا با همدیگه بریم شنا
توی ده شلمرود
حسنی دیگه تنها نبود!
بعد از این که حسنی تمیز شد و با همه بازی کرد، همه دور هم جمع شدند و از بابای حسنی خواستند که ازشون عکس بگیره. ولی وقتی بابای حسنی اومد، فهمیدند که حداکثر تاشون درون یه عکس جا میشوند. بابای حسنی گفت: «خب حالا عیبی نداره، تا تا بیایید ازتون عکس میگیرم.»
مرغه گفت: «اینطوری که نمیشه، من میخوام با جوجههام توی یه عکس باشم.»
الاغه گفت: «تازه من هم میخوام با خروسه توی یه عکس باشم. اگه اینطوریه، من اصلا عکس نمیگیرم.»
بابای حسنی یه ذره مِنومِن کرد و گفت: «خب عیبی نداره. شما بیایید توی یه صف وایسید، بعد هم تا جایی که جا شدید میآیید توی عکس»
بالاخره اهالی ده شلمرود تصمیم گرفتند که به تا دسته تقسیم بشوند و توی دستهی ام نفر بودند که میخواستند با هم عکس بگیرند. حالا بابای حسنی از شما میپرسد که حداقل باید چند تا عکس بگیرد تا همه در یک عکس افتاده باشند.
در هر عکسی که بابای حسنی میگیرد یک بازه پشت سر هم از دستهها میتوانند حضور داشته باشند که جمع اعضای این بازه باید حداکثر باشد.
در واقع شما یه آرایهی تایی دارید و باید بگید حداقل چقدر هست که بتوان آرایه را به بازه تقسیم کرد که مجموع اعداد هر بازه حداکثر باشد.
توجه کنید که بازه به دنبالهای متوالی از اعضای یک آرایه گفته میشود.
ورودی شامل دو خط است. در خط اول به ترتیب ابتدا تعداد گروهها و سپس حداکثر ظرفیت یک عکس به شما داده میشود.
در خط دوم عدد به شما داده میشود که عدد ام آنها، است.
خروجی برنامه شامل یک عدد صحیح است، حداقل تعداد عکسهایی که پدر حسنی باید بگیرد.
بازهها به صورت خواهند بود. یک جواب دیگر برای این مثال است.
اگر دسته اول و دوم نتوانند در یک عکس باشند، (یعنی ) حتما دسته اول باید تنهایی عکس بگیرند و با دسته دیگری نمیتوانند در یک عکس باشند.
در چه صورت جواب بهینهای وجود دارد که دسته اول و دوم هر دو در یک عکس باشند؟
ثابت کنید اگر دسته دوم میتوانست در عکس با دسته اول باشد (یعنی ) جواب بهینهای وجود دارد که دسته اول و دوم هر دو در یک عکس باشند.
اگر دسته اول و دوم با هم نمیتوانستند در یک عکس باشند، یک عکس تکی از دسته اول بگیرید.
اگر دسته اول و دوم میتوانستند با هم باشند، این دو دسته را یک دسته جدید با اندازه در نظر بگیرید و مسئله را دوباره حل کنید.
دسته اول را در عکس اول قرار بدهید. سپس دسته دوم را اگر میشد، در عکس قرار بدهید، سپس دسته سوم و به همین روال ادامه دهید تا زمانی که دیگر نمیتوانید دسته جدیدی قرار بدهید.
فرض کنید t دسته اول را در عکس اول قرار دادید و نمیتوانید دسته بعدی را در عکس قرار بدهید. حالا t دسته اول حذف شدند و با همین روش بقیه افراد را در عکس قرار بدهید.
در واقع از اولین دسته شروع کنید و تاجایی که میتوانید دستهها را در داخل عکس قرار بدهید.
اثبات درستی به صورت خلاصه این است که در هر مرحله اگر دستهای رو می توانید قرار بدهید. دلیلی وجود ندارد که قرار ندهید و عکس بگیرید چون این دسته باید در عکس بعدی قرار بگیرد و میتوانست در عکس اول باشد و در عکس دوم نباشد.
درستی الگوریتم را با استقرا نیز میتوانید اثبات کنید چون دسته اول و دوم را در صورت امکان میتوانید یک دسته بکنید و تعداد دستهها کم میشود.
حسنی برای این که در تابستان وقتش را تلف نکند به کسب و کار روی آورده و به تازگی بانکی به نام کناب تاسیس کرده است.
از آنجایی که دوست دارد شما نیز عضو کناب باشید به شما یک پروژه داده و خواسته تا همراهبانکی بنویسید که درخواستهای زیر را اجرا کند.
این درخواست یعنی کاربری با نام کاربری username و آیپی ip به همراهبانک وصل شد و در صورتی که username معتبر نباشد باید عبارت invalid username
را چاپ کنید.
به یک نام کاربری معتبر میگوییم اگر فقط از حروف کوچک و بزرگ انگلیسی و اعداد تشکیل شده باشد.
برای مثال 1aAB2
معتبر است ولی ab*2
معتبر نیست.
این درخواست یعنی کاربری با آیپی ip به حسابی با نام کاربری username به اندازه money پول ریخته است. در واقع باید از حساب ip به اندازه money کم کنید و به حساب username اضافه کنید.
با داده شدن این درخواست مقدار پول داخل حساب فرد با آیپی ip را نمایش دهید.
(دقت کنید که پول هر فرد میتواند منفی هم بشود و هرکس در ابتدا ۰ واحد پول دارد)
در اولین خط ورودی عدد که بیانگر تعداد درخواستها است به شما داده میشود و در خط بعد، در هر خط یک درخواست داده میشود.
در هر درخواست ابتدا type داده میشود که برابر یکی از اعداد ۱ یا ۲ یا ۳ است و اگر برابر با ۱ باشد در ادامه دو رشته ip و username به شما داده میشود که توسط کاراکتر :
از هم جدا شدهاند. اگر
مساوی ۲ باشد سه رشته ip و username و
money
داده میشود که با :
از هم جدا شدهاند و اگر هم مساوی ۳ باشد رشته ip داده میشود.
طول username و ip حداکثر ۱۵ است.
تضمین میشود که:
_
یا *
یا #
یا $
در آن به کار رفته باشد. برای هر درخواست نوع ۱ در صورتی که username معتبر نیست باید عبارت invalid username
را چاپ کنید و برای هر درخواست نوع ۳ باید مقدار پول حساب فرد خواسته شده را چاپ کنید. (پاسخ هر درخواست را در یک خط جدید چاپ کنید.)
توضیحات:
نام کاربری #hacker$user
معتبر نیست برای همین باید invalid username
خروجی بدهید.
از حساب SmsS
هزار واحد پول کم میشود و به حساب faeila
اضافه میشود و حالا SmsS
منفی هزار و faeila
هزار واحد پول دارد.
از حساب faeila
پانصد واحد کم میشود و حالا پانصد واحد پول دارد و SmsS
منفی پانصد.
برای پیادهسازی تمیز این سوال میتوانید از Regex یا عبارت باقاعده و Associative array یا آرایه انجمنی استفاده کنید.
میتوانید این لینک را نیز برای پیدا کردن Associative array در زبان مورد نظرتان استفاده کنید.
سعید کنید Associative arrayای بسازید که هر کاربر که اضافه شد، بتوان با استفاده از نامکاربری هر فرد، آیپی آن فرد را پیدا کرد.
حالا Associative array دیگری بسازید که با استفاده از آیپی هر فرد بتوان موجودی حساب آن فرد را پیدا کرد و یا تغییر داد.
حالا میتوانید با استفاده از آیپی یا نامکاربری به موجودی حساب هر فرد دسترسی داشته باشید و درخواستها را انجام بدهید.
فرض کنید sender_ip
برابر آیپی فردی است که پول واریز میکند و receiver_user
برابر نام کاربری فردی است که پول دریافت میکند. میخواهیم دو مقدار receiver_money
را که برابر پول حساب دریافت کننده است و همچنین sender_user
و sender_money
که نام کاربری و پول حساب واریز کننده است را پیدا کنیم.
و دو Associative array به نامهای get_user
و get_money
داریم که با اولی میتوان با دادن آیپی فرد نام کاربری آن را به دست آورد و با استفاده از دومی، با دادن نام کاربری فرد، مقدار پول حسابش را به دست آورد.
شبه کد الگوریتم برای اعمال کوئریهای نوع اول:
شبه کد الگوریتم برای اعمال کوئریهای نوع دوم:
در کشور(!) شلمرود، شهر وجود دارد که با جاده دوطرفه به هم وصل شدهاند. طول جاده ام هم کیلومتر است. حسنی یک الاغ هم دارد که با استفاده از آن میتواند با سرعت یک کیلومتر بر ساعت جادهها را طی کند.
حسنی جدیدا یک قابلیت جدید پیدا کرده که با استفاده از آن میتواند طول همه جادهها را یک کیلومتر کم کند. حسنی فقط میتواند این قابلیت را وقتی درون یک شهر هست استفاده کند و ساعت طول میکشد که از این قابلیت در راس -ام استفاده کند. همچنین اگر با استفاده از این قابلیت طول یک جاده صفر بشود آن جاده از شلمرود حذف میشود و نمیتوان از آن عبور کرد.
حالا حسنی از شما میپرسد که کمترین زمانی که طول میکشد تا از شهر شماره به شهر شماره برسه چه قدر هست و از آنجا که شما هم حسنی را خیلی دوست دارید باید جوابش را بدهید.
در خط اول ورودی و آمده است. سپس در خط بعدی عدد آمده که عدد -ام را نشان میدهد. در هر یک از خط بعدی هم سه عدد آمده که دو سر جاده و وزن آن جاده را مشخص میکند.
در تنها خط خروجی کمترین زمان برای رسیدن از شهر شماره به شهر شماره را چاپ کنید. در صورتی هم که مسیری از شهر به شهر وجود نداشته باشد -1
چاپ کنید.
در این نمونه وقتی که در شهر یک هستیم بار از قابلیت استفاده میکنیم و بعد از آن طول هر دو جاده یک میشود. بعد از آن میتوان بعد از دو ساعت به شهر شماره سه رسید.
در این مثال بدون استفاده از قابلیت میتوان بعد از ساعت به شهر رسید.
در این نمونه مسیری از شهر به شهر وجود ندارد.
برای حل این سوال باید الگوریتم Dijkstra را بلد باشید.
به مجموعهای از شهرها و جادهها گراف میگوییم و منظور از راس همان شهر و از یال همان جاده است.
اگر فرض کنید گراف اولیه برابر باشد. گراف را به این صورت تعریف کنید که راسها و یالهای آن متنظار با راسها و یالهای است ولی طول هر یال آن منهای i شده و اگر منفی میشد، حذف شده است.
میتوانید مشاهده کنید که همان است.
با استفاده از ها گرافی بسازید که مسئله شما صرفا به مسئله کوتاه ترین مسیر تبدیل شود و پیچیدگی دیگری نداشته باشد.
دقت کنید که اگر روی راس v در گراف باشید میتوانید در مدت زمان به راس متناظر v در گراف بروید.
میتوانید مشاهده کنید که هیچ یالی ندارد چون
میخواهیم گراف جدیدی بسازیم که از اتصال های مخلتف است.
به این صورت این گراف را میسازیم که برای هر i () و هر راس مثل v در ، آن را توسط یک یال یک طرفه با وزن به شهر متناظرش در وصل میکنیم.
میتوانید مشاهده کنید که جواب معادل کوتاه ترین مسیر از شهر 1 در به یکی از شهرهای n در یکی از ها است که طول مسیر کمینه شود از طرفی به بعد چون هیچ یالی ندارند نیازی بهشون نداریم پس تعداد راسهای ما برابر و تعداد یالها حداکثر است که الگوریتم Dijkstra میتواند جواب مسئله را پیدا کند.
بابای حسنی به حسنی سوالی را داده و به او گفته تا این سوال را حل کند. اما چون حسنی زیاد علاقهای به حل سوال ندارد، از شما خواسته تا این سوال را برای او حل کنید.
آرایهای به نام به طول داریم. میخواهیم بلندترین زیردنبالهای از آرایه را پیدا کنیم که صعودی-نزولی باشد.
حسنی به دنباله صعودی-نزولی میگوید اگر سه شرط زیر برای آن برقرار باشد:
حال شما باید طول بلندترین زیردنبالهای از آرایه که صعودی-نزولی است را پیدا کنید و آن را چاپ کنید.
نکته: به آرایه یک زیردنباله از آرایه میگوییم اگر بتوان با حذف تعدادی عضو از آرایه به آرایه رسید.
در اولین خط ورودی عدد و در خط بعدی عدد امده است که عدد ام مقدار خانه ام آرایه است.
در تنها خط خروجی طول بلندترین زیردنباله صعودی-نزولی را بگویید.
برای مثال دنباله یکی از جوابهای ممکن است.
در این حالت کل آرایه صعودی-نزولی است.
اگر دو عنصر متوالی و مساوی وجود داشت، میتوانیم یکی را به دلخواه حذف کنیم چون در جواب مسئله تاثیری ندارد.
اگر سه عنصر متوالی وجود داشته باشد که صعودی باشند یعنی اولی کمتر از دومی و دومی کمتر از سومی باشد میتوانیم عنصر دوم را حذف کنیم. (چرا؟)
اگر دنبال بهینهای وجود داشته باشد که عنصر وسط (یعنی دوم) در این دنباله باشد طبق تعریف دنباله صعودی-نزولی، ممکن نیست هر سه عنصر در این دنباله باشند. پس میتوان جای عنصر دوم یکی از دو عنصر که استفاده نشده را قرار داد. (در صورتی که این عنصر، اندیس فرد داشت جای آن عنصر بعدی که بزرگتر است (و در نتیجه بهتر است) را قرار میدهیم و در غیر این صورت عنصر دیگر)
اگر k عنصر متوالی صعودی وجود داشت طبق راهنمایی قبل فقط اولی و اخری را نگه میداریم و بقیه را حذف میکنیم.
همینطوری اگر k عنصر متوالی نزولی وجود داشت اولی و اخری را نگه میداریم و بقیه را حذف میکنیم.
بعد از حذف عنصرهای اضافه که در راهنمایی ۲ گفته شد، میتوانید مشاهده کنید که دنباله باقیمانده، یک دنباله صعودی-نزولی است. البته ممکن است نیاز باشد اولین عنصر را نیز حذف کنید در صورتی که عنصر اولی بزرگتر از عنصر بعدی باشد.
دنباله جدید صعودی - نزولی است چون عضو دوم بزرگتر از عضو اول است و اگر عنصر سوم بزرگتر از دومی باشد سه عنصر متوالی صعودی پیدا شده که تناقض دارد. پس عنصر سوم کوچکتر از عنصر دومی است. حالا اگر عنصر چهارم کوچکتر از عنصر سوم باشد دوباره سه عنصر متوالی نزولی پیدا شده که تناقض دارد پس عنصر چهارم بزرگتر از عنصر سوم است.
اگر همین روال را ادامه بدهیم میبینیم که دنباله صعودی-نزولی است.
از طرفی این دنباله بلندترین است چون دنبال بهینهای وجود داشته باشد که عنصر وسط (یعنی دوم) در این دنباله باشد طبق تعریف دنباله صعودی-نزولی ممکن نیست هر سه عنصر در این دنباله باشند پس میتوان جای عنصر دوم یکی از دو عنصر که استفاده نشده را قرار داد (در صورتی که این عنصر، اندیس فرد داشت جای آن عنصر بعدی که بزرگتر است (و در نتیجه بهتر است) را قرار میدهیم و در غیر این صورت عنصر دیگر)
آرایه ، شامل اعداد روی تخته نوشته شده است. در هر گام میتوانیم یکی از دو عملیات زیر را انجام دهیم.
از عملیات نوع دوم حداکثر بار میتوانیم استفاده کنیم.
کمترین تعداد مرحله برای این که در انتها کلا عددی روی تخته باقی نماند، یا تمامی اعداد باقی مانده برابر با باشد، چهقدر است؟
ورودی شامل دو خط است که خط اول آن شامل دو عدد است.
در خط دوم عدد میآید که اعداد اولیه روی تخته را مشخص میکند.
در تنها خط خروجی کمترین مراحل مورد نیاز برای رسیدن به شرایط مطلوب را چاپ کنید.
یکی از روشها این است که ابتدا اعداد و را با عملیات نوع اول به تبدیل کنیم. سپس عدد را به تبدیل کنیم، اعداد روی تخته خواهند بود. در نهایت عدد را پاک کنیم و دنباله تهی میشود. در مجموع عملیات انجام شده است.
در یکی از روشهای بهینه ابتدا عدد را حذف میکنیم، سپس را با عملیات اول به تبدیل میکنیم و نهایتا همه اعداد را با عملیات اول به صفر تبدیل میکنیم.
در این بخش فرض کنید است.
نمایش باینری اعداد را در نظر بگیرید، با عملیات اول آخرین رقم نمایش دودویی حذف میشود. اکنون درخت ترای اعداد آرایه را در نظر بگیرید، هدف این است که با حذف آخرین رقم همه اعداد را به صفر تبدیل کنیم که یعنی درخت ترای اعدادمان را تک راسی کنیم، پس میتوان دریافت که به حداقل به اندازه تعداد راسهای ترای منهای یک، عملیات نیاز داریم، چون در هر عملیات حداکثر یک راس حذف میشود.
همینطور میتوان روشی ارائه داد تا با دقیقا همین تعداد عملیات، همه اعداد را به صفر تبدیل کنیم.
پس مساله در حالت ، حل شد. سعی کنید با همین ایده مساله را برای حل کنید.
در این بخش به بیان ایده حالت کلی مساله میپردازیم.
با استفاده از برنامهنویسی پویا روی درخت ترای مساله را حل میکنیم. فرض کنید بخواهیم برای هر راس در درخت ترای مثل (که متناظر با یک عدد است) ، مساله را برای اعداد درون زیردرخت آن راس حل کنیم، یعنی بخواهیم با عملیات حذف ، اعداد درون زیردرخت را به تبدیل کنیم.
برای محاسبه این مقادیر به این نتیجه میرسیم که لازم است روی این که آیا همه اعداد زیردرخت حذف شدهاند یا خیر حالتبندی کنیم در نتیجه لازم است آرایه ایداشته باشیم که کمترین تعداد عملیاتهای نوع اول لازم برای اینکه اعداد درون زیردرخت را به تبدیل کنیم و حداکثر بار ار عملیات حذف استفاده کنیم. همچنین اگر تضمین میشود که همه اعداد درون این زیردرخت حذف شدهاند و هیچ عددی باقی نمانده است و درحالت ، ممکن است تعدادی از اعداد (طبیعتا همگی هستند)، باقی بمانند.
در این بخش شیوه پرکردن آرایه را شرح میدهیم.
فرض کنید بخواهیم را محاسبه کنیم.
فرزند چپ را و فرزند راست آن را بنامید.
حالت بندی کنید که چه تعداد عملیات حذف را در زیردرخت و چه تعداد را در زیر درخت استفاده کنیم، همچنین با حالت بندی روی اینکه در هر کدام از زیردرختها کل اعداد حذف شدهاند یا خیر، میتوان دریافت که یک عملیات اضافه برای تبدیل و یا به نیاز داریم یا خیر.
همچنین یک حالت این است که روی عملیات حذف را انجام دهیم که نباید آن را فراموش کنید.
در نهایت پیچیدگی نهایی حل این مساله خواهد بود.
اگر دنبالهای از اعداد داشته باشید به اولین عدد طبیعیای که در آن ظاهر نشده Mex آن دنباله میگوییم.
برای مثال Mex دنباله برابر و Mex دنباله برابر است.
دنباله به شما داده شده است و باید جمع Mex تمام زیربازههای آن را به دست بیاورید. (در مجموع زیربازه داریم.)
در واقع اگر را برابر Mex زیر دنباله تعریف کنیم، شما باید مقدار زیر را چاپ کنید.
در سطر اول ورودی عدد و در سطر دوم عدد به شما داده میشود که عدد -ام برابر عضو ام دنباله است.
در تنها خط خروجی مقدار خواسته شده را نمایش دهید.
توضیح:
و Mex زیربازههایی که ۱ را ندارند برابر ۱ است.
فرض کنید برای هر پیشوند از ارایه Mex را به دست آوردید. حالا عنصر اول را حذف کنید و Mex هر پیشوند را حساب کنید.
بعد از حذف عنصر اول، پیشنودهایی که Mex آن کمتر از بودند تغییری نمیکنند.
بعد از حذف عنصر اول در صورتی که Mex پیشنوندی قرار باشد تغییر کند، مقدار آن برابر میشود.
اگر برابر Mex پیشوندی باشد که به i ختم می شود. میتوانید مشاهده کنید که دنباله زیر صعودی است:
و وقتی عنصر اول را حذف میکنید، اگر دومین تکرار این عنصر در اندیس x باشد. (یعنی ) برای هر مقدار ممکن است عوض شود و بقیه تغییری نمیکنند چون قبلا در خانه اول وجود داشته و تمام پیشوندهایی که از خانه x رد میشودند هنوز را دارند. و از طرفی برای هر کدام از آن iها مقدار مینیمم گرفته میشود با چون ممکن است این عنصر اولین کسی باشد که دیگر در بازه نیست.
پیاده سازی الگوریتم با درخت سگمنت یا BST امکان پذیر است.