AGC002E Candy Piles

Posted yllcm

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AGC002E Candy Piles相关的知识,希望对你有一定的参考价值。

不会推结论?使用数据结构!

尝试考虑 \\(n=1,n=2,n=3\\) 的必败必胜条件,寻找一些结论,但是发现即使是 \\(n=3\\) 胜负情况已经有些不可描述了,说明我们必须尝试转化问题的形式。

注意到操作是全局减,常见的转化是差分,但是差分后的操作仍然没有优秀的性质。

继续思考,可以得到一个恰当的转化:注意到游戏结束当且仅当最大值 \\(\\leq 0\\),那么可以维护两个数 \\(now,x\\),每次可以选择 \\(now\\gets now-1,x\\gets x+1\\),若状态满足 \\(a_now\\leq x\\) 则为必胜态。那么问题转化为一个网格游走问题,每次可以向左或者向上,边界为必胜态。

画图可以发现状态是有规律的但是我没有看出来,所以考虑按列考虑,维护出每列的状态,考虑一些简单的情况:

  • \\(a_2=6,a_1=4\\),发现 \\(x=3\\)\\(x=4\\) 会有两个连续的必胜态,其余状态必胜和必败相间分布。
  • \\(a_i+1=7,a_i=6\\)\\(x=3,x=4\\) 有两个连续的必胜态,发现转移后 \\(x=2,x=3\\) 有两个连续的必胜态,其余状态必胜和必败相间分布。
  • \\(a_i+1=8,a_i=6\\)\\(x=3,x=4\\) 有两个连续的必胜态,发现转移后 \\(x=2,x=3\\) 以及 \\(x=5,x=6\\) 有两个连续的必胜态,其余状态必胜和必败相间分布。
  • \\(a_i+1=8,a_i=6\\)\\(x=5,x=6\\) 有两个连续的必胜态,转移后所有状态必胜和必败相间分布。

归纳可得规律:

  • \\(a_i+1\\)\\(a_i\\) 奇偶性相同。
    • \\(x=a_i,x=a_i-1\\) 处不是连续必胜态,会在 \\(x=a_i,x=a_i-1\\) 两个位置插入连续必胜态,并平移其它状态。
    • 否则,会删除这两个连续必胜态,并平移其它状态。
  • \\(a_i+1\\)\\(a_i\\) 奇偶性不同,则平移其它状态。

使用支持单点加,单点删,全局加的数据结构维护即可,下面使用了 set,复杂度 \\(\\mathcalO(n\\log n)\\)

https://atcoder.jp/contests/agc002/submissions/40819016

@atcoder - AGC002E@ Candy Piles


@description@

给定 N 堆糖果,第 i 堆包含 ai 个糖果。

现在两人进行博弈。有两种操作选择:
(1)吃掉包含最多糖果的糖果堆。
(2)每堆吃掉一颗。

吃掉最后一颗糖的人判输,问谁必胜?

原题传送门。

@solution@

将 n 个数从大到小排好序,看成一个 n 列的直方图,第 i 列包含 a‘i 个格子。

举个例子:对于 5 5 3 2 1 1,可以建立直方图如下:
o o
o o
o o o
o o o o
o o o o o o

那么相当于有一个棋子从 (1, 1) 出发,玩家可以将棋子右/上移一步,走出边界的判输。

然后经过万能的打表找规律,我们可以发现如果 (x, y) 和 (x + 1, y + 1) 同时存在,则两者的 np 状态。
不过这个结论利用反证法倒是不难证就是了。。。

于是我们可以先移动到一个点 (x, y) 使得 (x + 1, y + 1) 不存在,注意到从 (x, y) 只能一路向上或右,两种情况都判一判即可。

@accepted code@

#include <cstdio>
#include <algorithm>
using namespace std;

const int MAXN = 100000;

bool cmp(int x, int y) {return x > y;}

int a[MAXN + 5], N;
int main() {
    scanf("%d", &N);
    for(int i=1;i<=N;i++)
        scanf("%d", &a[i]);
    sort(a + 1, a + N + 1, cmp);
    for(int i=1;i<=N;i++) {
        if( a[i + 1] < i + 1 ) {
            int p = (a[i] - i) % 2, q;
            for(int j=i;j<=N+1;j++)
                if( a[j] < i ) {
                    q = (j - i - 1) % 2;
                    break;
                }
            puts(p & 1 || q & 1 ? "First" : "Second");
            break;
        }
    }
}

@details@

这是什么神仙操作.jpg。

我怎么觉得 E 比 F 难。F 题我好歹会切,E 题完全没有办法。

以上是关于AGC002E Candy Piles的主要内容,如果未能解决你的问题,请参考以下文章

@atcoder - AGC002E@ Candy Piles

AtCoder - 1999 Candy Piles

AGC027 A - Candy Distribution Again

[AtCoder AGC27A]Candy Distribution Again

[leetcode] 875. 爱吃香蕉的珂珂(周赛)

Codeforces Round #575 (Div. 3) (A. Three Piles of Candies)(数学)