【AGC002 E】Candy Piles
本来实在写不动这题 sol 了,但一想这是个经典的模型转化问题,于是就写了(.jpg)
题意
有一个序列 \(a_i\)。
两人轮流操作,每次操作为二选一:
1. 把最大的 \(a_i\) 减成 \(0\)
2. 把所有非 \(0\) 的 \(a_i\) 减去 \(1\)
若一个人操作后,所有 \(a_i\) 都是 \(0\),这个人就输了。
两人都采用轮流策略,问谁能赢。
\(n\le 10^5\)
\(a_i\le 10^9\)
题解
智商模型转化:把所有 \(a_i\) 从大到小排序,画一个柱状图,第 \(i\) 个柱子的高度为 \(a_i\)。每个人可以删去最左边一列或最下边一行,求谁操作后删光整个柱状图。

我们发现每次操作后,图的左下角一定会移动,并且一个左下角对应一种游戏局面。
所以,这个模型还可以转化:从左下角出发,两人轮流向上或向右走一个单位,走到边界的人输。

这是个很简单的博弈论 \(\text{dp}\),每个点对应一个操作者的必胜态 / 必败态。将操作者的胜败状态记在该操作到达的点上,则边界上全是必败态,\((1,1)\) 是后手的胜败状态(因为先手从这里出发到邻点,胜败状态在两个邻点上,通过那两个点的胜败状态算出的胜败状态 相当于后手在游戏开始时的胜败状态)。
直接 \(O(n\times a_i)\) \(\text{dp}\) 即可求出每个点是必胜态还是必败态。
但这样显然会 T,我们考虑优化。
随便画一个图,手玩出每个点的胜败状态(红圈表示必败态,蓝叉表示必胜态)

不难发现左下-右上对角线上的状态都是一样的!如何证明?
假如 \((x,y)\) 是 \(1\),\((x-1,y-1)\) 不可能是 \(0\)。这里用反证法,举一个例子:
0 ?
1 1 ?
0 1 0
注意到 \(0\) 的后继全都是 \(1\),\(1\) 的后继一定有 \(0\)。
可以画出这样的图。
发现两个 ? 处至少有一个 \(0\)(\(1\) 的后继一定有 \(0\)),但两个 ? 处都必须是 \(1\)(\(0\) 的后继全部是 \(1\)),因此矛盾。
以上图为例,我们就只需要算 \((4,4)\) 的胜败状态了!
这个位置怎么算呢?
它的上边、右边所有点都贴着边界,状态为胜、败轮流交替。于是可以从
以上图为例,从 \((4,7)\) 往下根据奇偶性推出 \((4,5)\) 的状态,从 \((8,4)\) 往左推出 \((5,4)\) 的状态,然后根据 \((4,5)\) 和 \((5,4)\) 的状态就可以推出 \((4,4)\longrightarrow (1,1)\) 的状态了。
复杂度 \(O(n)\)。
#include<bits/stdc++.h>
using namespace std;
int a[100005];
int main(){
int n,i;
scanf("%d",&n);
for(i=1; i<=n; ++i) scanf("%d",&a[i]);
sort(a+1, a+n+1, greater<int>());
for(i=1; i<=n; ++i){
if(i<=a[i] && a[i+1]<i+1){
int j=0;
while(a[j+i+1]==i) j++;
if((a[i]-i)%2==0 && j%2==0) puts("Second");
else puts("First");
return 0;
}
}
}
【AGC002 E】Candy Piles的更多相关文章
- 【AGC002E】Candy Piles 博弈论
题目大意 有\(n\)堆糖果,第\(i\)堆有\(a_i\)个. 两个人轮流决策,决策分为两种: 1.选择糖果数最多的一堆糖果,并把这堆糖全吃了. 2.在每堆非空的糖果堆里拿一颗糖吃掉. 吃掉最后一颗 ...
- 【LEETCODE OJ】Candy
Problem link: http://oj.leetcode.com/problems/candy/ Suppose we are given an array R[1..N] that are ...
- 【LeetCode练习题】Candy
分糖果 There are N children standing in a line. Each child is assigned a rating value. You are giving c ...
- 【ZOJ 3897】Candy canes//Fiddlesticks
题 题意 给你一串数,a1...an,从左到右每次让一个数减小c,如果这个数小于c,那就减为0.第n个数减小后,又从第一个开始从左到右.如果这次某个数减小到0,那就改变方向,如果遇到已经是0的,就跳过 ...
- 【HDOJ 5654】 xiaoxin and his watermelon candy(离线+树状数组)
pid=5654">[HDOJ 5654] xiaoxin and his watermelon candy(离线+树状数组) xiaoxin and his watermelon c ...
- 【Unity Shader】Unity Chan的卡通材质
写在前面 时隔两个月我终于来更新博客了,之前一直在学东西,做一些项目,感觉没什么可以分享的就一直没写.本来之前打算写云彩渲染或是Compute Shader的,觉得时间比较长所以打算先写个简单的. 今 ...
- 【赛事总结】◇赛时·8◇ AGC-027
[赛时·8]AGC-027 日常AGC坑……还好能涨Rating +传送门+ ◇ 简单总结 感觉像打多校赛一样,应该多关注一下排名……考试的时候为了避免影响心态,管都没有管排名,就在那里死坑B题.最后 ...
- 【24.67%】【codeforces 551C】 GukiZ hates Boxes
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- DFS【搜索1】
DFS模板 void dfs(int depth)//depth表示当前的层数(或深度) { if(depth>n)//到达叶子节点,该路已走到尽头 return; for(int i=;i&l ...
随机推荐
- 【Matlab开发】MATLAB编译C/C++代码
在使用MATLAB编译C/C++代码时,C/C++代码中要使用一个mexFunction函数,那么这个函数是如何定义,在编译时又是如何实现的呢?下面我将使用实例进行说明. 如一个简单的函数: doub ...
- 【VS开发】EasySize使用设置CFormView空间自适应view窗口大小
1.在stdafx.h中引用EasySize.h头文件(同时将EasySize.h放到你的程序目录中) 2.在类定义中添加DECLARE_EASYSIZE [cpp] view plain copy ...
- FTL-SLC&MTC&TLC
1.博客 SLC.. http://diybbs.zol.com.cn/67/231_661182.html 2.FTL --作者在普及了一些FTL基本知识后,主要分析了在linux上实现的途径 ht ...
- history 命令
history 命令用来显示执行过的命令,也可以根据显示的命令重新执行需要的命令. 用法: n 显示n个最近的记录 -a 添加记录到history文件中 -c 将目前shell中的所有history命 ...
- EMR日常操作
1/ 数据root密码修改后emr配置修改: 2/ 添加s3访问 S3:hadoop-aws-2.8.5.jarjar -tfv hadoop-aws-2.8.5.jar |grep S3FileSy ...
- spark-scala-java实现wordcount
引入:spark-scala-java实现wordcount 1.spark-scala实现wordcount package com.cw.scala.spark import org.apache ...
- sqlserver bcp命令导出数据
原文:sqlserver bcp命令导出数据 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net ...
- $listeners 在vue中的使用 --初学
事件回传之 $listeners 组件由下向上回传事件 <!doctype html><html lang="en"> <head> <m ...
- django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块
CBV加装饰器 第一种 @method_decorator(装饰器) 加在get上 第二种 @method_decorator(login_auth,name='get') 加在类上 第三种 @met ...
- JavaScript设计模式(单例模式)
单例模式是一种简单但非常实用的模式,特别是惰性单例技术,在合适的时候才创建对象,并且只创建唯一的一个.下面我们来逐步了解单例模式的用法. 一.简版单例模式: var Singleton = funct ...