مؤلف المشكلة: | هايدارا المكديد |
أعدها: | هايدارا المكديد |
حررها: | حسن صالح (نموذج رياضي) |
الحل
نريد تعظيم قيمة
بعد اختيار فهارس مميزة بالضبط واستبدال كل a_i المختار بـ NOT الثنائي 32 بت \sim a_i. بما أن يتم على 32 بت، يمكننا التفكير فيه كـ \sim x = (2^{32}-1) - x، أو بشكل مكافئ \sim x = (\texttt{MASK} \,\hat{}\, x) مع \texttt{MASK} = 2^{32}-1.
دع الجواب النهائي يكون . لكل بت يكون في ، يجب أن يكون لكل عنصر في المصفوفة النهائية أيضًا تلك البتة تساوي ، وإلا سيكون AND في تلك الموضع . هذا يشير إلى بناء بشكل جشع بتًا بتًا من البت الأكثر أهمية إلى الأقل أهمية: نحن نحافظ على إجابة حالية ans، ولكل بت من إلى نحاول تعيينه إلى فوق ما قمنا بتثبيته بالفعل.
بشكل ملموس، عند البت نشكل قيمة مرشحة
مما يعني أننا نريد أن يكون AND النهائي لديه جميع البتات التي هي في cand. للتحقق من إمكانية تحقيق cand، نقوم بفحص الجدوى على المصفوفة بأكملها. لكل عنصر x = a_i هناك حالتان فقط في التكوين النهائي: إما أن نحتفظ به كما هو ، أو نقلبه إلى y = \sim x = (\texttt{MASK} - x). لكي تكون cand قابلة للتحقيق، يجب أن يغطي كل موضع على الأقل أحد هذه الخيارات جميع بتات cand:
عند النظر إلى (\text{keep\_ok}, \text{flip\_ok}) نقسم الفهارس إلى ثلاثة أنواع مفيدة:
إذا كان كلاهما خاطئًا، فإن لا ولا يحتويان على جميع بتات cand، لذا لا يمكن لهذا الفهرس أن يحقق cand أبدًا. ثم cand نفسها مستحيلة ويجب علينا رفض هذه البتة.
إذا كانت \text{keep\_ok} = \text{false} و \text{flip\_ok} = \text{true}، فنحن مجبرون على قلب هذا الفهرس لتحقيق cand. دع يكون عدد هذه الفهارس المجبورة.
إذا كانت \text{keep\_ok} = \text{true} و \text{flip\_ok} = \text{true}، فإن هذا الفهرس مرن: كل من الاحتفاظ والقلب لا يزالان يحققان cand. دع يكون عدد هذه الفهارس المرنة.
(عندما تكون \text{keep\_ok} = \text{true} و \text{flip\_ok} = \text{false} يجب علينا ببساطة الاحتفاظ بالعنصر؛ فهو لا يستهلك أي قلب ولا يعطي أي مرونة.)
يجب علينا إجراء بالضبط قلبات بشكل عام. بالنسبة إلى cand الثابتة، يجب قلب جميع الفهارس المجبورة ، لذا نحتاج على الأقل إلى قلبات. من ناحية أخرى، يمكننا اختيارًا قلب أي مجموعة من الفهارس المرنة ، لذا فإن العدد الإجمالي للقلبات التي يمكننا تحقيقها مع الاستمرار في تحقيق cand يتراوح من (فقط المجبورة) إلى F+C (المجبورة بالإضافة إلى جميع المرنة). لذا فإن cand قابلة للتحقيق إذا وفقط إذا
إذا كانت هذه المعادلة صحيحة، نعلم أنه يوجد طريقة لاختيار بالضبط فهارس لقلبها بحيث تغطي كل عنصر نهائي جميع بتات cand. في هذه الحالة نقبل هذه البتة ونضبط \texttt{ans} := \texttt{cand}. إذا لم يكن، نترك البتة عند في ans وننتقل إلى البتة التالية الأقل.
لأننا نعالج البتات من الأكثر أهمية إلى الأقل ونقوم بتعيين بتة فقط عندما توجد بعض التكوينات من قلبات التي تدعم جميع البتات المختارة حتى الآن، فإن ans الناتجة هي الحد الأقصى النهائي الممكن لـ AND بشكل ترتيب (وبالتالي عدديًا). لكل من مواضع البت نقوم بفحص جميع العناصر مرة واحدة، لذا فإن التعقيد العام هو O(32n) = O(n) من حيث الوقت و ذاكرة إضافية بخلاف مصفوفة المدخلات.
n,k=map(int, input().split())
a=list(map(int, input().split()))
MASK=(1<<32)-1
ans=0
for j in range(31, -1, -1):
p=1<<j
cand = ans | p
forced = 0
flex = 0
ok = True
for x in a:
keep = (x & cand) == cand
flipped = (~x) & MASK
flip = (flipped & cand) == cand
if not keep and not flip:
ok = False
break
if not keep and flip:
forced += 1
elif keep and flip:
flex += 1
if not ok:
continue
rem = k - forced
if rem < 0 or rem > flex:
continue
ans = cand
print(ans)