[SG函数]吃吃吃

Description

桌上摆着NN坨糖果(不要吐槽量词),分别标号为1~N,一开始时第ii坨糖果里有aiai颗糖。

すぬけ君和青木君准备用这N坨糖玩一个游戏。他们轮流操作,すぬけ先手。每一次操作,必须从以下两种操作中选一个执行:

1. 选择糖果数最多的一坨糖果,并把这坨糖全吃了。
2. 在每坨非空的糖果堆里拿一颗糖吃掉。

吃掉最后一颗糖的人将输掉游戏。假设这两个人都足够ниуби(都会选择最优策略),请你算出哪个人最终会取得胜利。

Input

输入第一行包含一个整数NN,第二行包含NN个整数a1,a2,...,aN。

Output

如果すぬけ最终能获胜,输出"First",否则输出"Second"。

Sample Input

## Sample Input 1
    2
    1 3
    
## Sample Input 2
    3
    1 2 1
    
## Sample Input 3
    3
    1 2 3

Sample Output

## Sample Output 1
    First

## Sample Output 2
    First

## Sample Output 3
    Second

HINT

1≤N≤1e5
1≤ai≤1e9

有40分的子任务满足1N,ai2000

分析

从大到小排序后把糖果画成条形图,容易发现操作其实是在取走最左一列或最下一行

然后DP打个表可以发现对角线的SG值相等

然后我们只需要找到经过0,0的对角线在图形上的最后一个交点,其上方糖果数或右方糖果数为偶即可获胜

 

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=1e5+10;
int a[N],n;

bool CMP(int a,int b) {return a>b;}

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,j;i<=n;i++)
        if (a[i+1]<i+1) {
            for (j=i;i==a[j+1];j++);
            printf((((j-i)&1)|((a[i]-i)&1))?"First":"Second");
            return 0;
        }
}
View Code

 

posted @ 2019-09-18 21:53  Vagari  阅读(173)  评论(0编辑  收藏  举报