BZOJ_3729_Gty的游戏_博弈论+splay+dfs序

Description

某一天gty在与他的妹子玩游戏。
妹子提出一个游戏,给定一棵有根树,每个节点有一些石子,每次可以将不多于L的石子移动到父节点,询问
将某个节点的子树中的石子移动到这个节点先手是否有必胜策略。
gty很快计算出了策略。
但gty的妹子十分机智,她决定修改某个节点的石子或加入某个新节点。
gty不忍心打击妹子,所以他将这个问题交给了你。
另外由于gty十分绅士,所以他将先手让给了妹子。

Input

第一行两个数字,n和L,n<=5*10^4,L<=10^9
第二行n个数字,表示每个节点初始石子数。
接下来n-1行,每行两个整数u和v,表示有一条从u到v的边。
接下来一行一个数m,表示m组操作。
接下来m行,每行第一个数字表示操作类型
若为1,后跟一个数字v,表示询问在v的子树中做游戏先手是否必胜。
若为2,后跟两个数字x,y表示将节点x的石子数修改为y。
若为3,后跟三个数字u,v,x,表示为u节点添加一个儿子v,初始石子数为x。
在任意时刻,节点数不超过5*10^4。

Output

对于每个询问,若先手必胜,输出"MeiZ",否则输出"GTY"。
另,数据进行了强制在线处理,对于m组操作,除了类型名以外,都需要异或之前回答为"MeiZ"的个数。

Sample Input

2 1000
0 0
1 2
1
1 1

Sample Output

GTY

阶梯Nim博弈,和根节点层数奇偶相同的层可以当做没有。
因为对于每个由奇变偶的石子,都可以再由偶变奇,相当于偶数层的没有用。
同时每次最多取L个,相当于这样一个问题:
求奇数层上所有石子%(L+1)的异或和。
splay维护一下。
一开始以为只需要维护出栈序,然后发现插入不太好插。于是维护出栈入栈序。
插入直接插两个点。
 
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 400050
#define ls ch[p][0]
#define rs ch[p][1]
#define get(x) (ch[f[x]][1]==x)
int ch[N][2],f[N],sum[N],s1[N],s2[N];
int head[N],to[N<<1],nxt[N<<1],cnt,n,L,rt,dfn[N],val[N],a[N],son[N],m,w[N],dep[N],D[N],sz;
inline void add(int u,int v) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
void pushup(int p) {
if(!p) return ;
// s2[p]=val[p]; s1[p]=0;
if(D[p]&1) s1[p]=val[p],s2[p]=0;
else s1[p]=0,s2[p]=val[p];
// if(ls) s2[p]=(s2[p]+s1[ls])%L,s1[p]=(s1[p]+s2[ls])%L;
// if(rs) s2[p]=(s2[p]+s1[rs])%L,s1[p]=(s1[p]+s2[rs])%L;
if(ls) s2[p]^=s2[ls],s1[p]^=s1[ls];
if(rs) s2[p]^=s2[rs],s1[p]^=s1[rs];
}
void rotate(int x) {
int y=f[x],z=f[y],k=get(x);
ch[y][k]=ch[x][!k]; f[ch[y][k]]=y;
ch[x][!k]=y; f[y]=x; f[x]=z;
if(z) ch[z][ch[z][1]==y]=x;
if(rt==y) rt=x;
pushup(y); pushup(x);
}
void splay(int x,int y) {
for(int d;(d=f[x])!=y;rotate(x))
if(f[d]!=y)
rotate(get(x)==get(d)?d:x);
}
void dfs(int x,int y) {
int i;
dfn[x]=++sz; a[sz]=w[x]; D[sz]=dep[x];
for(i=head[x];i;i=nxt[i]) {
if(to[i]!=y) {
dep[to[i]]=dep[x]+1;
dfs(to[i],x);
}
}
son[x]=++sz;
}
void build(int l,int r,int fa) {
if(l>r) return ;
int mid=(l+r)>>1;
f[mid]=fa; ch[fa][mid>fa]=mid;
val[mid]=a[mid];
build(l,mid-1,mid);
build(mid+1,r,mid);
pushup(mid);
}
int suc() {
int p=ch[rt][1];
while(ls) p=ls;
return p;
}
int main() {
scanf("%d%d",&n,&L); L++;
int i,x,y;
for(i=1;i<=n;i++) scanf("%d",&w[i]),w[i]%=L;
for(i=1;i<n;i++) {
scanf("%d%d",&x,&y); add(x,y); add(y,x);
}
dep[1]=1;
sz++;
dfs(1,0);
sz++;
build(1,sz,0);
rt=(sz+1)>>1;
scanf("%d",&m);
int opt,z;
int ans=0;
while(m--) {
scanf("%d%d",&opt,&x);
x^=ans;
// printf("%d\n",opt);
if(opt==1) {
// printf("%d %d\n",m,x);
// printf("%d %d\n",dfn[x],son[x]);
// printf("%d %d\n",dfn[x],rt);
splay(dfn[x],0);
// printf("%d %d\n",dfn[x],rt);
if(dfn[x]!=rt) {puts("FUCK"); break;} splay(son[x],dfn[x]);
int re=(dep[x]&1)?s2[ch[son[x]][0]]:s1[ch[son[x]][0]];
if(re) ans++,puts("MeiZ");
else {puts("GTY");}
}else if(opt==2) {
scanf("%d",&y); y^=ans;
// val[dfn[x]]=y%L; for(i=dfn[x];i;i=f[i]) pushup(i);
splay(dfn[x],0); val[dfn[x]]=y%L; pushup(dfn[x]);
}else if(opt==3) {
scanf("%d%d",&y,&z); y^=ans; z^=ans;
dep[y]=dep[x]+1;
splay(dfn[x],0);
int p=suc();
splay(p,rt);
dfn[y]=++sz; son[y]=++sz; val[dfn[y]]=z%L;
f[dfn[y]]=p; ls=dfn[y]; f[son[y]]=dfn[y]; ch[dfn[y]][1]=son[y];
D[dfn[y]]=dep[y];
pushup(son[y]); pushup(dfn[y]); pushup(p); pushup(rt);
}
}
}

BZOJ_3729_Gty的游戏_博弈论+splay+dfs序的更多相关文章

  1. BZOJ_3252_攻略_线段树+dfs序

    BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...

  2. BZOJ_2017_[Usaco2009 Nov]硬币游戏_博弈论+DP

    BZOJ_2017_[Usaco2009 Nov]硬币游戏_博弈论+DP Description 农夫约翰的奶牛喜欢玩硬币游戏,因此他发明了一种称为“Xoinc”的两人硬币游戏. 初始时,一个有N(5 ...

  3. 【BZOJ-3786】星系探索 Splay + DFS序

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

  4. BZOJ3786: 星系探索 Splay+DFS序

    题目大意:给你一个树,支持三种操作,子树加,点到根的路径和,改变某一个点的父亲. 分析: 看起来像一个大LCT,但是很显然,LCT做子树加我不太会啊... 那么,考虑更换一个点的父亲这个操作很有意思, ...

  5. BZOJ 3786 星系探索 (splay+dfs序)

    题目大意:给你一棵树,支持一下三种操作 1.获取某节点到根节点的路径上所有节点的权值和 2.更换某棵子树的父亲 3.某子树内所有节点的权值都增加一个值w 当时想到了splay维护dfs序,查完题解发现 ...

  6. 【NOI2019集训题2】 序列 后缀树+splay+dfs序

    题目大意:给你一个长度为$n$的序列$a_i$,还有一个数字$m$,有$q$次询问 每次给出一个$d$和$k$,问你对所有的$a_i$都在模$m$意义下加了$d$后,第$k$小的后缀的起点编号. 数据 ...

  7. BZOJ_2434_[NOI2011]_阿狸的打字机_(AC自动机+dfs序+树状数组)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=2434 给出\(n\)个字符串,\(m\)个询问,对于第\(i\)个询问,求第\(x_i\)个字 ...

  8. bzoj3786 星际探索 splay dfs序

    这道题 首先 因为他求的是当前点到根节点的路径和 我们可以将题目转换为括号序列的写法 将点拆为左括号以及右括号 左括号为正 右括号为负 这样题目就变为了求前缀和了 如果一个点是这个点的子树 那么他的左 ...

  9. BZOJ2690: 字符串游戏(平衡树动态维护Dfs序)

    Description 给定N个仅有a~z组成的字符串ai,每个字符串都有一个权值vi,有M次操作,操作分三种: Cv x v':把第x个字符串的权值修改为v' Cs x a':把第x个字符串修改成a ...

随机推荐

  1. 只列出所有监听 UNIX 端口 netstat -lx

    只列出所有监听 UNIX 端口 netstat -lx

  2. css3 - 基本选择器

    有人说类选择器最好不要超过三层,其实我也是这样认为的,不是吗? 选择器分为四大类 标签.全选(相对于子类继承了0.1).类.ID 权值分别是:1->0.1->10->100(权值可叠 ...

  3. Odoo 运费

    模块delievery可以将运费Charge给客户     安装delivery模块                 Delivery method     在做订单的时候,选择相应的运输方法, 系统 ...

  4. Odoo HRMS应用简介

    Odoo HRMS包含行政管理的大部分功能,包含 部门组织架构 员工清册 岗位规划以及招聘管理 用工合同 考勤管理 休假和加班 费用报销 员工考核 绩效.激励.培训成绩 薪资清册     个角色 角色 ...

  5. jquery $.proxy使用 Jquery实现ready()的源码

    jquery $.proxy使用   在某些情况下,我们调用Javascript函数时候,this指针并不一定是我们所期望的那个.例如: 1 //正常的this使用 2 $('#myElement') ...

  6. fuser - identify processes using files or sockets

    FUSER(1) User Commands FUSER(1) NAME fuser - identify processes using files or sockets SYNOPSIS fuse ...

  7. 关于提高沟通能力的书单zz

    上周推荐了一份关于提高写作能力的书单,这周,我们来聊聊沟通能力. 在现代社会,沟通能力变得越来越重要.人与人之间的社交渠道越来越丰富,工作中的协同合作也越来越普遍.我们要沟通的人越来越多,节奏越来越快 ...

  8. slidemenu

    1. 在github上有一个效果不错的开源库,SlidingMenu 最新的代码下载下来后,会报错: No resource found that matches the given name: at ...

  9. 实现单击列表头对ListView的动态排序

    排序是根据列的类型来的,就ID列来说,int类型的排序结果是3,5,17,而如果你把该列类型改为string,结果就会是17,3,5,如果你定义列的时候不加类型,默认是string,如果是自定义类型, ...

  10. Subversion基础:概念、安装、配置和基本操作(转)

    本文转载至http://www.cnblogs.com/cokecoffe/archive/2012/06/01/2537130.html 转自:http://www.uml.org.cn/pzgl/ ...