题意:

给定一棵有根树,每个节点有一些石子,每次可以将不多于k的石子移动到父节点

修改一个点的石子数,插入一个点,询问某棵子树是否先手必胜


显然是一个阶梯Nim

每次最多取k个,找规律或者观察式子易发现就是$mod (k+1)$后的Nim

问题变为:

修改点权,插入点,询问某棵子树内某一深度的点权异或和

于是放大招了:伪$ETT$

真正的ETT貌似维护的是边,欧拉遍历序列也是边组成的序列

但我们用Splay来维护欧拉遍历的点的序列,入栈出栈时都加入队列,+1,-1,好像也叫括号序列

$build$过程中保存下每个点入栈和出栈对应的Splay上的节点编号,入栈正出栈负(一开始节点编号和序列编号是一样的)

本题的子树不需要根所以询问子树只要把那段区间splay出来就行了,需要根的找出区间的前驱后继splay他们就好了

加入新节点,分配两个dfs序编号给它,把新父亲和后继splay出来然后连上再更新就行了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define lc t[x].ch[0]
#define rc t[x].ch[1]
#define pa t[x].fa
#define pii pair<int, int>
#define MP make_pair
#define fir first
#define sec second
typedef long long ll;
const int N=1e5, INF=1e9;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
} int n, m, k, a[N], Q, op, x, y, z, id[N]; struct edge{int v, ne;} e[N<<];
int cnt, h[N];
inline void ins(int u, int v) {
e[++cnt]=(edge){v, h[u]}; h[u]=cnt;
}
int eul[N<<], dfc, deep[N];
pii dfn[N];
void dfs(int u) {
dfn[u].fir = ++dfc; eul[dfc]=u;
for(int i=h[u];i;i=e[i].ne)
deep[e[i].v] = deep[u]^, dfs(e[i].v);
dfn[u].sec = ++dfc; eul[dfc]=-u;
} struct meow{int ch[], fa, v, sg[], deep;} t[N<<];
int root;
inline int wh(int x) {return t[pa].ch[] == x;}
inline void update(int x) {
t[x].sg[] = t[lc].sg[]^t[rc].sg[];
t[x].sg[] = t[lc].sg[]^t[rc].sg[];
t[x].sg[t[x].deep] ^= t[x].v;
} inline void rotate(int x) {
int f=t[x].fa, g=t[f].fa, c=wh(x);
if(g) t[g].ch[wh(f)] = x; t[x].fa=g;
t[f].ch[c] = t[x].ch[c^]; t[t[f].ch[c]].fa=f;
t[x].ch[c^]=f; t[f].fa=x;
update(f); update(x);
}
inline void splay(int x, int tar) {
for(; pa!=tar; rotate(x))
if(t[pa].fa != tar) rotate(wh(x)==wh(pa) ? pa : x);
if(tar==) root=x;
} void build(int &x, int l, int r, int f) {
int mid = (l+r)>>; x=mid;
t[x].fa=f; t[x].deep = deep[abs(eul[mid])];
if(eul[mid]>) t[x].v = a[eul[mid]];
if(l<mid) build(lc, l, mid-, x);
if(mid<r) build(rc, mid+, r, x);
update(x);
} int Que(int u) {
int p = dfn[u].fir; splay(p, );
int x = dfn[u].sec; splay(x, p);
return t[lc].sg[deep[u]^] > ;
}
void ChaVal(int u, int d) {
int x = dfn[u].fir; splay(x, );
t[x].v = d; update(x);
}
inline int nex(int x) {
x = rc; while(lc) x = lc; return x;
}
void Add(int u, int v, int d) {
int p = dfn[u].fir; splay(p, );
int x = nex(p); splay(x, p); int a = ++dfc, b = ++dfc;
dfn[v] = MP(a, b);
t[a].ch[] = b; t[b].fa = a;
t[a].fa = x; t[x].ch[] = a;
t[a].v = d; t[a].deep = t[b].deep = deep[v] = deep[u]^;
update(a); update(x); update(p);
} int main() {
freopen("in","r",stdin);
n=read(); k=read()+;
for(int i=; i<=n; i++) a[i]=read()%k, id[i]=i;
for(int i=; i<n; i++) x=read(), y=read(), ins(x, y);
dfs(); build(root, , dfc, );
Q=read();
int meizi=, ans;
for(int i=; i<=Q; i++) {
op=read();
x=read()^meizi; x=id[x];
if(op==) ans=Que(x), meizi+=ans, puts(ans ? "MeiZ" : "GTY");
else {
y=read()^meizi;
if(op==) ChaVal(x, y%k);
else z=(read()^meizi)%k, Add(x, id[y]=++n, z);
} }
return ;
}

BZOJ 3729: Gty的游戏 [伪ETT 博弈论]【学习笔记】的更多相关文章

  1. BZOJ 3729 GTY的游戏

    伪ETT? 貌似就是Splay维护dfn = = 我们首先观察这个博弈 这个博弈直接%(l+1)应该还是很显然的 因为先手怎么操作后手一定能保证操作总数取到(l+1) 于是就变成阶梯Nim了 因为对于 ...

  2. BZOJ 3729 - Gty的游戏(Staircase 博弈+时间轴分块)

    题面传送门 介于自己以前既没有写过 Staircase-Nim 的题解,也没写过时间轴分块的题解,所以现在就来写一篇吧(fog 首先考虑最极端的情况,如果图是一条链,并且链的一个端点是 \(1\),那 ...

  3. BZOJ 3729 Gty的游戏 ——Splay

    很久很久之前,看到Treap,好深啊 很久之前看到Splay,这数据结构太神了. 之后学习了LCT. 然后看到Top-Tree就更觉得神奇了. 知道我见到了这题, 万物基于Splay 显然需要维护子树 ...

  4. 【BZOJ 3729】3729: Gty的游戏 (Splay维护dfs序+博弈)

    未经博主同意不得转载 3729: Gty的游戏 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 448  Solved: 150 Description ...

  5. lua游戏开发实践指南学习笔记1

    本文是依据lua游戏开发实践指南做的一些学习笔记,仅用于继续自己学习的一些知识. Lua基础 1.  语言定义: 在lua语言中,标识符有非常大的灵活性(变量和函数名),只是用户不呢个以数字作为起始符 ...

  6. html5游戏引擎-Pharse.js学习笔记(一)

    1.前言 前几天随着flappy bird这样的小游戏的火爆,使我这种也曾了解过html5技术的js业余爱好者也开始关注游戏开发.研究过两个个比较成熟的html5游戏引擎,感觉用引擎还是要方便一些.所 ...

  7. BZOJ 2820: YY的GCD [莫比乌斯反演]【学习笔记】

    2820: YY的GCD Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1624  Solved: 853[Submit][Status][Discu ...

  8. BZOJ 3786: 星系探索 [伪ETT]

    传送门 数据,标程 题意: 一颗有根树,支持询问点到根路径权值和,子树加,换父亲 欧拉序列怎么求路径权值和? 一个点的权值只会给自己的子树中的点贡献,入栈权值正出栈权值负,求前缀和就行了! 和上题一样 ...

  9. [BZOJ3786]星系探索(伪ETT)

    3786: 星系探索 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1638  Solved: 506[Submit][Status][Discuss ...

随机推荐

  1. Spark环境搭建(中)——Hadoop安装

    1. 下载Hadoop 1.1 官网下载Hadoop http://www.apache.org/dyn/closer.cgi/hadoop/common/hadoop-2.9.0/hadoop-2. ...

  2. Xtrabackup实现数据的备份与恢复

    Xtrabackup介绍 Xtrabackup是由percona开源的免费数据库热备份软件,它能对InnoDB数据库和XtraDB存储引擎的数据库非阻塞地备份(对于MyISAM的备份同样需要加表锁): ...

  3. Solr6.0与Jetty、Tomcat在Win环境下搭建/部署

    摘要: Solr6的新特性包括增强的edismax,对SQL更好的支持--并行SQL.JDBC驱动.更多的SQL语法支持等,并且在Solr6发布以后,Solr5还在持续更新,对于想尝鲜Solr6的用户 ...

  4. win10清除桌面快捷方式小箭头

    reg add /d "%systemroot%\system32\imageres.dll,197" /t reg_sz /f taskkill /f /im explorer. ...

  5. 对SVD奇异值分解的理解

      首先推荐一篇博客,奇异值分解(SVD)原理详解及推导 - CSDN博客,讲解的很清楚.这里我谈谈自己的理解,方便以后回顾.   如果把向量理解为空间中的一个元素,那么矩阵可以理解为两个空间上的映射 ...

  6. Struts2 05---拦截器

    一.Struts2拦截器原理: Struts2拦截器的实现原理相对简单,使用了aop思想和责任链模式,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截 ...

  7. 读书笔记之《Java编程思想》

    17. 容器 Set 存入Set的每个元素都必须是唯一的,因为Set不保存重复元素. Set接口不保证维护元素的次序 Map 映射表(关联数组)的基本思想是维护的是键-值(对)关联,因此可以用键来查找 ...

  8. hive导出查询文件到本地文件的2种办法

    通过HQL语句 可以将hive 中表的数据生成到指定的目录. 有时候 我们可以利用hive来生成统计的中间文件(比源文件小的多的) 方法有如下2种: 1.INSERT OVERWRITE LOCAL ...

  9. Mybatis问题:There is no getter for property named 'unitId' in 'class java.lang.String'

    Mybatis遇到的问题 问题: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.re ...

  10. 引用类型之数组array最全的详解

    Array类型 今天总结一下array类型. js中的数组是有着非常强大的功能.具有很大的灵活性,有两个方面的特点 1.数组的每一项可以保存任何的数据类型:2.数组大小可以动态的调整:看下面的例子: ...