Comment

avatar username

There's an $O(n)$ time for 2178D — Xmas or Hysteria.

Idea is almost same as editorial, except that we now need a strategy $S$ that runs in linear time and does the following :

On input any sequence of elves $Elves[i,...,j]$, output a sequence of valid attacks such that at the end there's exactly one or zero elf remains.

Now suppose we have such magic $S$, then

for $m \ge 1$ case : same as editorial, except that we're gonna use std::nth_element to put the largest $m$ elves in $I = Elves[n-m+1,...,n]$ and the second largest $m$ elves in $II = Elves[n-2m+1,...,n-m]$. Also we're gonna deal with the remaining $n-2m$ elves with our magic $S$ (in the case that there's one elf remains, let it attack any elf in $II$). Finally, we do a parallel scan of $I$ and $II$ and let elves in $I$ attack elves in $II$.

for $m = 0$ case : still very similar to editorial. Suppose we pass the sum check (otherwise no solution). First swap the strongest to $Elves[n]$ and second strongest to $Elves[n-1]$, then starting at $i=1$, while $Elves[i].attack < strongest.hp$, let $i$ attack strongest and strongest.hp -= Elves[i].attack, then ++i. The while loop terminates when we reach an elf Alice where $Alice.attack \ge strongest.hp$ (it's guaranteed that this occurs and Alice $\neq$ strongest due to the initial sum check). Now deal with the elves between Alice (inclusive) and $2nd$ strongest (exclusive) using our magic $S$. If there's one elf remaining, let it attack the $2nd$ strongest. Finally, let $2nd$ strongest punch the strongest (this punch will kill the strongest as $strongest.hp \le Alice.attack \le 2ndStrongest.attack$).

Here's one possible way to design our magic strategy $S$. The idea is to be greedy and always let the dying elf to attack. We're going to do a linear scan over the input $Elves[i,...,j]$. Suppose we're now at $p$, lets call $Elves[p]$ Alice and $Elves[p+1]$ Bob. The invariant is that (1) Alice has never attacked before (2) Bob will always have full hp. Then some case analysis

if(Alice.hp <= Bob.attack){
    if(Alice.attack > Bob.attack){
        //both will die, it doesn't matter who attacks who
        let Alice attack Bob
        p+=2 //skip both Alice and Bob
    }else{
        //only Alice will die
        let Alice attack Bob //valid by invariant
        Bob.hp -= Alice.attack
        p++
    }
}else{
    //only Bob will die
    let Bob attack Alice //valid by invariant, full hp means not attacked before
    Alice.hp -= Bob.attack
    Elves[p+1] = Alice
    p++
}

please check invariant is maintained for all cases. It's clear that either one or zero elf remains when we finish.

The actual rating of this user is 462.

Original comment.

Statistics