【主席树维护mex】 【SG函数递推】 Problem H. Cups and Beans 2017.8.11
Problem H. Cups and Beans 2017.8.11
原题:
There are N cups numbered 0 through N − 1. For each i(1 ≤ i ≤ N − 1), the cup i contains Ai beans,
and this cup is labeled with an integer Ci.
Two people will play the following game:
• In each turn, the player chooses a bean from one of the cups except for the cup 0.
• If he chooses a bean from the cup i, he must move it to one of the cups i − Ci;…… ; i − 1.
• The players take turns alternately. If a player can’t choose a bean, he loses.
Who will win if both players play optimally?
Input:
Input Format:
N
C(1) A(1)
C(2) A(2)
…
C(N−1) A(N−1)
Constraints:
• 2 ≤ N ≤ 105
• 1 ≤ Ci ≤ i
• 0 ≤ Ai ≤ 109
• At least one of Ai is nonzero.
• All values in the input are integers.
Output:
Print the name of the winner: \First” or \Second”.
Examples:
| standard input | standard output |
| 3 1 0 1 1 |
Second |
| 7 1 1 2 0 1 0 2 0 4 1 3 0 |
First |
| 7 1 1 2 0 1 9 2 10 4 3 3 5 |
Second |
Note:
Notes to the Sample 1:
• In the first turn, the first player must move a bean from 2 to 1.
• In the second turn, the second player must move a bean from 1 to 0.
• In the third turn, the first player can’t choose a bean and loses.
题目大意:
典型的博弈论,N个瓶子,第一个瓶子里没有石子,后面N-1个瓶子里分别有A[i]个石子,每个瓶子上贴了标签C[i],表示每次操作仅可以将这个瓶子里的一个石子石子最多可以移动到前面C[i]个瓶子里(也就是只可以将该瓶子里的一个石子放到 i-C[i] 到 i-1 号瓶子里),最后不能进行移动的人输,求谁赢。
解法分析:
可以将这个问题转化成限定条件的Nim取石子问题,题目的操作是将高位瓶子的石子移动到低位瓶子里,那么石子所在的瓶子标号其实就可以认为是石子堆的石子数,对于每个特定数量的石子堆 i,都有一个限定条件 C[i] 表示最多取i个,A[i] 则表示石子数为i的石子堆有A[i]个。
知道了题意,就可以直接暴力了,枚举前面的 i-C[i] 到 i – 1 的状态然后递推。可是数据范围是1e5,这样做无疑会超时,在周大爷的敏锐观察下,套用了一个主席树维护mex数的模板,就过了。
代码:
#include <bits/stdc++.h> #define MAXN 100005
using namespace std;
typedef long long LL; #define lc(x) t[x].l
#define rc(x) t[x].r
const int N = 2e5 + , MX = 1e9 + ; struct node {
int l, r, mn;
} t[N * ];
int sz, root[N]; void ins(int &x, int l, int r, int p, int v) {//right of p is v
t[++sz] = t[x];
x = sz;
if (l == r) t[x].mn = v;
else {
int mid = (l + r) >> ;
if (p <= mid) ins(t[x].l, l, mid, p, v);
else ins(t[x].r, mid + , r, p, v);
t[x].mn = min(t[lc(x)].mn, t[rc(x)].mn);
}
} int query(int x, int l, int r, int v) {
if (l == r) return l;
else {
int mid = (l + r) >> ;
if (t[lc(x)].mn < v) return query(t[x].l, l, mid, v);
else return query(t[x].r, mid + , r, v);
}
} int SG[], n;
bool vis[];
int C[], A[]; int main() {
int i, j, k;
scanf("%d", &n);
for (i = ; i < n; i++) {
scanf("%d%d", &C[i + ], &A[i + ]);
}
SG[] = ;
ins(root[],,MX,SG[],);//ins是插入操作,root[1]表示当前树,0表示最小值,MX表示最大值,SG[0]是值,1是位置
for (i = ; i <= n; i++) {
int l = max(i - C[i], ), r = i - ;
SG[i] = query(root[r], , MX, l);
root[i] = root[i-];
ins(root[i],,MX,SG[i],i);
}
// for(int i = 1;i <= n;i++) printf("%d ",SG[i]);
int ans = ;
for (i = ; i <= n; i++) {
if (A[i] % == ) ans ^= SG[i];
}
if (ans) printf("First\n");
else printf("Second\n");
return ;
}
【主席树维护mex】 【SG函数递推】 Problem H. Cups and Beans 2017.8.11的更多相关文章
- 牛课练习赛34 Flittle w and Discretization 主席树维护Mex
ittle w and Discretization 主席树维护Mex. 每个右端点 r 维护出一棵 在[1, r ] 区间中 其他所有的 值离这个 r 最近的的位置是多少. 然后询问区间[L,R]的 ...
- 【博弈论】【SG函数】【线段树】Petrozavodsk Summer Training Camp 2016 Day 9: AtCoder Japanese Problems Selection, Thursday, September 1, 2016 Problem H. Cups and Beans
一开始有n个杯子,每个杯子里有一些豆子,两个人轮流操作,每次只能将一个豆子移动到其所在杯子之前的某个杯子里,不过可以移动到的范围只有一段区间.问你是否先手必胜. 一个杯子里的豆子全都等价的,因为sg函 ...
- 一类SG函数递推性质的深入分析——2018ACM陕西邀请赛H题
题目描述 定义一种有根二叉树\(T(n)\)如下: (1)\(T(1)\)是一条长度为\(p\)的链: (2)\(T(2)\)是一条长度为\(q\)的链: (3)\(T(i)\)是一棵二叉树,它的左子 ...
- UVa 10561 (SG函数 递推) Treblecross
如果已经有三个相邻的X,则先手已经输了. 如果有两个相邻的X或者两个X相隔一个.,那么先手一定胜. 除去上面两种情况,每个X周围两个格子不能再放X了,因为放完之后,对手下一轮再放一个就输了. 最后当“ ...
- Light OJ 1296 - Again Stone Game (博弈sg函数递推)
F - Again Stone Game Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu ...
- CodeForces 464E The Classic Problem | 呆克斯歘 主席树维护高精度
题意描述 有一个\(n\)点\(m\)边的无向图,第\(i\)条边的边权是\(2^{a_i}\).求点\(s\)到点\(t\)的最短路长度(对\(10^9 + 7\)取模). 题解 思路很简单--用主 ...
- 【10.10校内测试】【线段树维护第k小+删除】【lca+主席树维护前驱后驱】
贪心思想.将a排序后,对于每一个a,找到对应的删除m个后最小的b,每次更新答案即可. 如何删除才是合法并且最优的?首先,对于排了序的a,第$i$个那么之前就应该删除前$i-1$个a对应的b.剩下$m- ...
- 【洛谷5294】[HNOI2019] 序列(主席树维护单调栈+二分)
点此看题面 大致题意: 给你一个长度为\(n\)的序列\(A\),每次询问修改一个元素(只对当前询问有效),然后让你找到一个不下降序列\(B\),使得这两个序列相应位置之差的平方和最小,并输出这个最小 ...
- POJ_3090 Visible Lattice Points 【欧拉函数 + 递推】
一.题目 A lattice point (x, y) in the first quadrant (x and y are integers greater than or equal to 0), ...
随机推荐
- Oracle作业4-函数
一.在数据库中的emp和dept表中做如下查询: 1.列出所有分析师(ANALYST)的姓名.编号和部门 SELECT ENAME,EMPNO,E.DEPTNO,DNAME FROM EMP E,DE ...
- iOS 自定义任意形状加载进度条(水波纹进度条)
1. 项目中要做类似下面的加载动画: 先给出安卓的实现方式 2.iOS的实现方式参考了下面两位的,感谢. 以任意底部图片为背景的加载动画 和 水波纹动画 最后附上自己的demo
- Jquery中绑定事件与普通事件的区别
(“#panel”).bind(“click”,function(){ 与$(“#panel”).click(function(){ 有什么区别 ? 绑定可以同时加多个事件 如:$(“#panel”) ...
- Eclipse切换字体颜色
打开window-preferences
- Flask中那些特殊的装饰器
模板相关的装饰器 @app.template_global() 用法: @app.template_global() # 记得加括号 def jiafa(a, b): # 这个方法每调用一次就需要传一 ...
- mysql8.0新增用户及密码加密规则修改
MySQL8.0已经发布GA版,当前最新GA版本为8.0.12.虽然相对于之前版本,MySQL8.0没有加入新元素,但是,经过代码重构,MySQL8.0的优化器更加强大,同时也有一些新特性,如支持索引 ...
- Hive(8)-常用查询函数
一. 空字段赋值 1. 函数说明 NVL:给值为NULL的数据赋值,它的格式是NVL( value,default_value).它的功能是如果value为NULL,则NVL函数返回default_v ...
- 7、Linux应用程序地址布局
程序构成 在学习Linux应用程序开发时,经常会遇到如下概念: 代码段.数据段.BSS段(Block Started by Symbol,又名:未始化数据段) .堆(heap)和栈(stack).始化 ...
- rails中使用CarrierWave实现文件上传的功能
之前在用django写blog的时候头像上传和头像预览都是使用原生的js实现的,之前也有写了一篇blog.好了开始进入正题 rails中实现头像上传十分的方便,只要通过CarrierWave这个gem ...
- python--模块之random随机数模块
作用是产生随机数 import random random.random:用于生成一个0--1的随机浮点数. print(random.random())>>0.3355102133472 ...