BZOJ 3729 Gty的游戏 ——Splay
很久很久之前,看到Treap,好深啊
很久之前看到Splay,这数据结构太神了。
之后学习了LCT。
然后看到Top-Tree就更觉得神奇了。
知道我见到了这题,
万物基于Splay
显然需要维护子树查询,插入,子树修改。
Top-Tree?我不会。
直接用Splay维护欧拉序,然后拆成进入子树和离开两个节点,然后就可以方便的维护子树了。
本蒟蒻不会写,去hzwer抄了
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define mp make_pair #define maxn 200005 int n,m,L,mod;
int rt,ind,ynum,top;
int val[maxn],fa[maxn],ch[maxn][2],typ[maxn],sg[maxn][2];
int a[maxn],st[maxn],dep[maxn],pos[maxn][2]; map <int,int> id;
vector <int> e[maxn]; void update(int x)
{
int l=ch[x][0],r=ch[x][1];
sg[x][0]=sg[l][0]^sg[r][0];
sg[x][1]=sg[l][1]^sg[r][1];
sg[x][typ[x]]^=val[x];
} void rot(int x,int &k)
{
// printf("rot %d %d\n",x,k);
int y=fa[x],z=fa[y],l,r;
l=(ch[y][1]==x);r=l^1;
if(y==k)k=x;
else ch[z][ch[z][1]==y]=x;
fa[ch[x][r]]=y;fa[y]=x;fa[x]=z;
ch[y][l]=ch[x][r];ch[x][r]=y;
update(y);update(x);
} void splay(int x,int &k)
{
// printf("splay %d\n",x);
while (x!=k)
{
int y=fa[x],z=fa[y];
if (y!=k)
{
if (ch[y][0]==x^ch[z][0]==y) rot(x,k);
else rot(y,k);
}
rot(x,k);
}
} int build(int l,int r,int f)
{
if (l>r) return 0;
int mid=(l+r)/2;
if (st[mid]>0)
{
val[mid]=a[st[mid]];
pos[st[mid]][0]=mid;
}
else pos[-st[mid]][1]=mid;
typ[mid]=dep[abs(st[mid])]; fa[mid]=f;
ch[mid][0]=build(l,mid-1,mid);
ch[mid][1]=build(mid+1,r,mid);
update(mid);
return mid;
} void ins(int u,int v,int num)
{
splay(pos[u][0],rt);
int t=ch[rt][1]; while (ch[t][0]) t=ch[t][0];
int t1=++top,t2=++top;
pos[v][0]=t1;pos[v][1]=t2;
fa[t1]=t;fa[t2]=t1;
ch[t][0]=t1; ch[t1][1]=t2;
val[t1]=num; typ[t1]=typ[t2]=dep[v];
update(t2);update(t1);splay(t2,rt);
} void query(int x)
{
splay(pos[x][0],rt);
splay(pos[x][1],ch[rt][1]);
if (sg[ch[pos[x][1]][0]][dep[x]^1])
{
ynum++;
puts("MeiZ");
}
else puts("GTY");
} void dfs(int x)
{
// printf("DFs %d\n",x);
st[++top]=x;
for (int i=0;i<e[x].size();++i)
{
dep[e[x][i]]=dep[x]^1;
dfs(e[x][i]);
}
st[++top]=-x;
} int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
// freopen("in.txt","r",stdin);
n=read(); L=read(); mod=L+1;
for (int i=1;i<=n;++i)
{
a[i]=read()%mod;
id[i]=i;
}
for (int i=1;i<n;++i)
{
int u,v;u=read();v=read();
e[u].push_back(v);
}
dfs(1); rt=build(1,top,0);
m=read();
int opt,u,v,x;
while (m--)
{
opt=read();
if (opt==1)
{
v=read();
v^=ynum;
query(id[v]);
}
if (opt==2)
{
x=read(); x^=ynum;
v=read(); v^=ynum; v%=mod;
x=id[x];splay(pos[x][0],rt);val[rt]=v;
update(rt);
}
if (opt==3)
{
u=read(); u^=ynum;
v=read(); v^=ynum;
x=read(); x^=ynum;
u=id[u]; id[v]=++n;
dep[n]=dep[u]^1;
ins(u,n,x%mod);
}
}
}
BZOJ 3729 Gty的游戏 ——Splay的更多相关文章
- BZOJ 3729 - Gty的游戏(Staircase 博弈+时间轴分块)
题面传送门 介于自己以前既没有写过 Staircase-Nim 的题解,也没写过时间轴分块的题解,所以现在就来写一篇吧(fog 首先考虑最极端的情况,如果图是一条链,并且链的一个端点是 \(1\),那 ...
- BZOJ 3729: Gty的游戏 [伪ETT 博弈论]【学习笔记】
题意: 给定一棵有根树,每个节点有一些石子,每次可以将不多于k的石子移动到父节点 修改一个点的石子数,插入一个点,询问某棵子树是否先手必胜 显然是一个阶梯Nim 每次最多取k个,找规律或者观察式子易发 ...
- BZOJ 3729 GTY的游戏
伪ETT? 貌似就是Splay维护dfn = = 我们首先观察这个博弈 这个博弈直接%(l+1)应该还是很显然的 因为先手怎么操作后手一定能保证操作总数取到(l+1) 于是就变成阶梯Nim了 因为对于 ...
- 【BZOJ 3729】3729: Gty的游戏 (Splay维护dfs序+博弈)
未经博主同意不得转载 3729: Gty的游戏 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 448 Solved: 150 Description ...
- [BZOJ3729]Gty的游戏
[BZOJ3729]Gty的游戏 试题描述 某一天gty在与他的妹子玩游戏.妹子提出一个游戏,给定一棵有根树,每个节点有一些石子,每次可以将不多于L的石子移动到父节点,询问将某个节点的子树中的石子移动 ...
- bzoj 3991: [SDOI2015]寻宝游戏 虚树 set
目录 题目链接 题解 代码 题目链接 bzoj 3991: [SDOI2015]寻宝游戏 题解 发现每次答案就是把虚树上的路径*2 接在同一关键点上的点的dfs序是相邻的 那么用set动态维护dfs序 ...
- bzoj 3232: 圈地游戏
bzoj 3232: 圈地游戏 01分数规划,就是你要最大化\(\frac{\sum A}{\sum B}\),就二分这个值,\(\frac{\sum A}{\sum B} \geq mid\) \( ...
- [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash)
[BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash) 题面 扔很多次硬币后,用H表示正面朝上,用T表示反面朝上,会得到一个硬币序列.比如HTT表示第一次正面朝上, ...
- [BZOJ 3731] Gty的超级妹子树 (树分块)
[BZOJ 3731] Gty的超级妹子树 (树分块) 题面 给出一棵树(或森林),每个点都有一个值.现在有四种操作 1.查询x子树里>y的值有多少个 2.把点x的值改成y 3.添加一个新节点, ...
随机推荐
- uva297 Quadtrees (线段树思想,区间操作)
借鉴了线段数区间操作的思想,只是把一个结点的孩子扩展到了4个, 结点k,四个孩子编号分别为4*k+1,4*k+2,4*k+3,4*K+4,从零开始. 根据层数,确定权值. #include<cs ...
- Wannafly Union Goodbye 2016-A//初识随机化~
想来想去还是把这个题写下来了.自己在补题遇到了许多问题. 给出n(n<=1e5)个点,求是否存在多于p(p>=20)×n/100的点在一条直线上... 时限20s,多组数据,暴力至少n^2 ...
- CMDB数据库设计
title: CMDB 数据库设计 tags: Django --- CMDB数据库设计 具体的资产 服务器表和网卡.内存.硬盘是一对多的关系,一个服务器可以有多个网卡.多个内存.多个硬盘 hostn ...
- SQLServer锁原理和锁的类型
1.锁的用途 为了避免同时争夺数据库资源,将数据库加锁,只有拿到钥匙的用户才能使用: 2.锁的粒度 行锁(Row)--->页锁(Page)--->区锁(Partition 8个页)---- ...
- cocos2dx for lua 简单的翻牌动画
local x = 20 local y = display.height/2 for i = 1,16 do--创建16张 local cardFg = display.newSprite(&quo ...
- 一步一步构建iOS持续集成:Jenkins+GitLab+蒲公英+FTP
什么是持续集成 持续集成是一种软件开发实践,即团队开发成员经常集成它们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成.每次集成都通过自动化的构建(包括编译,发布,自动化测试)来 ...
- UI调试神器 for ios:Reveal的使用与破解
aaarticlea/jpeg;base64,/9j/4AAQSkZJRgABAQEAkACQAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aH
- Spring框架配置文件中有两个相同名字的bean,最后会覆盖掉一个bean
问题容易出现在多个人合作的项目中,定义bean的名字的时候发生重复. 可以配置当bean定义重复的时候抛出异常,结束程序,强制提示更改重复的bean.
- 【主席树 启发式合并】bzoj3123: [Sdoi2013]森林
小细节磕磕碰碰浪费了半个多小时的时间 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M ...
- node中的定时任务
node-schedule每次都是通过新建一个scheduleJob对象来执行具体方法. 时间数值按下表表示 * * * * * * ┬ ┬ ┬ ┬ ┬ ┬ │ │ │ │ │ | │ │ │ │ │ ...