QOJ.ac

QOJ

時間限制: 1 s 記憶體限制: 256 MB 總分: 100 难度: [顯示] 互動

#51. Popa

统计

«إنه خارج عن القانون وهو مشهور، Andrii Popa الشجاع.

ليلاً ونهاراً يمتطي جواده، يأخذ إتاوته من الطريق الرئيسي، وفي كل مكان في البلاد يفرّ صائدو اللصوص بأقصى ما يستطيعون من سرعة»

— "Andrii Popa"، Phoenix

لدى Ghiță متتالية $S$ مفهرسة بدءاً من $0$ تتكون من $N$ من الأوزان الصحيحة الموجبة. وبما أنه ملك جبال الكاربات، فإنه يريد إنشاء شجرة ثنائية تحمل عقدها الفهارس $0, 1, \ldots, N - 1$ بحيث يتحقق ما يلي:

  • يعطي الاجتياز الوسطي (inorder traversal) للشجرة العقد بترتيب تصاعدي للفهارس. يتكون الاجتياز الوسطي لشجرة ثنائية من الاجتياز الوسطي للشجرة الفرعية المتجذرة عند الابن الأيسر للجذر (إن وجد هذا الابن)، متبوعاً بفهرس الجذر، ثم متبوعاً بالاجتياز الوسطي للشجرة الفرعية المتجذرة عند الابن الأيمن للجذر (إن وجد هذا الابن).
  • إذا كانت العقدة $x$ هي الأب للعقدة $y$، فإن $S_x$ يقسم $S_y$.

نذكّر بأن الشجرة الثنائية هي بنية بيانات شجرية يكون فيها لكل عقدة ابنان على الأكثر، يُشار إليهما بالابن الأيسر والابن الأيمن.

لسوء الحظ، سرق الخارج عن القانون الشهير Andrii Popa المتتالية $S$، ولم يعد بإمكان Ghiță الوصول إليها مباشرة. وباستخدام تقنية متطورة (هاتفه المحمول)، يمكنه لأي متتاليتين جزئيتين متجاورتين $[a, b]$ و $[c, d]$ من $S$ معرفة ما إذا كان $\gcd[a, b]$ يساوي $\gcd[c, d]$، حيث $\gcd[x, y]$ هو القاسم المشترك الأكبر للأعداد $S_x, S_{x+1}, S_{x+2}, \ldots, S_y$. ولسوء الحظ، فإن هذه التقنية مكلفة للغاية — فإذا استخدمها Ghiță أكثر من $Q$ مرة، فسيتعين عليه دفع غرامة كبيرة. ساعده باستخدام هذه التقنية على الأكثر $Q$ مرة لبناء الشجرة المطلوبة. من المضمون أن هذا ممكن. سيُقبل أي حل صحيح.

التفاعل

يجب على المتسابق تضمين ملف الترويسة popa.h (في C / C++) أو تنفيذ popa.pas (في Pascal). يحتاج المتسابق إلى تنفيذ الدالة التالية:

int solve(int N, int* Left, int* Right);
function solve(N: LongInt, var Left, Right: array of LongInt): LongInt;

يجب أن تُرجع هذه الدالة جذر الشجرة، وأن تضبط $\text{Left}_i$ و $\text{Right}_i$ على الابن الأيسر والابن الأيمن للعقدة $i$ على الترتيب. إذا لم يكن للعقدة $i$ ابن أيسر، فيجب أن تكون قيمة $\text{Left}_i$ مساوية لـ $-1$. وإذا لم يكن للعقدة $i$ ابن أيمن، فيجب أن تكون قيمة $\text{Right}_i$ مساوية لـ $-1$. يشير Left و Right إلى مصفوفتين بحجم $N$ بالضبط تم تخصيصهما مسبقاً.

قد يتم استدعاء الدالة solve على الأكثر $5$ مرات خلال تشغيلة واحدة. ننصح بتوخي الحذر عند استخدام المتغيرات العامة.

يمكن للمتسابق استخدام الدالة التالية:

int query(int a, int b, int c, int d);
function query(a, b, c, d: LongInt): LongInt;

تُرجع هذه الدالة $1$ إذا وفقط إذا كان $\gcd[a, b]$ مساوياً لـ $\gcd[c, d]$، حيث $0 \le a \le b < N$ و $0 \le c \le d < N$، وتُرجع $0$ خلاف ذلك.

المهام الفرعية

المهمة الفرعية 1 (37 نقطة)

  • $N = 100$
  • $Q = 10000$

المهمة الفرعية 2 (24 نقطة)

  • $N = 1000$
  • $Q = 20000$

المهمة الفرعية 3 (39 نقطة)

  • $N = 1000$
  • $Q = 2000$

أمثلة

مثال على التفاعل من أجل $S = [12, 4, 16, 2, 2, 20]$ هو:

استدعاءات solve استدعاءات query بعد استدعاء solve
solve(6, Left, Right)
query(0, 1, 3, 5) تُرجع $0$
query(4, 5, 1, 3) تُرجع $1$
solve تُرجع $3$; Left يشير إلى [-1, 0, -1, 1, -1, -1]; Right يشير إلى [-1, 2, -1, 4, 5, -1]

ملاحظة

مثال على شجرة من النوع الذي يريده Ghiță للمثال السابق هو:

problem_51_9045a83d122fa86162a3e40ade701483.png

Discussions

About Discussions

The discussion section is only for posting: General Discussions (problem-solving strategies, alternative approaches), and Off-topic conversations.

This is NOT for reporting issues! If you want to report bugs or errors, please use the Issues section below.

Open Discussions 0
No discussions in this category.

Issues

About Issues

If you find any issues with the problem (statement, scoring, time/memory limits, test cases, etc.), you may submit an issue here. A problem moderator will review your issue.

Guidelines:

  1. This is not a place to publish discussions, editorials, or requests to debug your code. Issues are only visible to you and problem moderators.
  2. Do not submit duplicated issues.
  3. Issues must be filed in English or Chinese only.
Active Issues 0
No issues in this category.
Closed/Resolved Issues 0
No issues in this category.