未经博主同意不得转载

3729: Gty的游戏

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 448  Solved: 150

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

HINT

Source

【分析】

  膜奥爷爷啦~~

  好吧,就是首先,阶梯尼姆,很明显吧。就是把距离根节点为奇数层的异或起来就好了。

  那就是差不多维护子树的异或和,但是树是动态的。【表示动态树我真的很垃圾,splay忘光,LCT不会,前面做的题都是离线的【如果离线就很快就会做了

所以接下来要学学动态树了。。

  用splay维护dfs序,和之前差不多嘛,一棵树的子树的dfs序记录了st和ed之后,查询区间[st,ed]就行了。

  splay就是能求出键值在某范围里面的东西【具体维护什么,和啊,最大值啊,都是你决定的】,但实际splay树上维护的是splay树子树上的东西。

  这时,你只要把st splay到跟,ed splay到根的右儿子,那么ed的做儿子表示的区间就是[st+1,ed-1]你直接问它的子树就好了。

  实际上,并不需要实际的dfs序,只要你按顺序插入的,那splay树就是有序的,你记录每个点的st和ed,到时找前驱后继就好了。

  可以选择看图:

  

  左图是原树,右图是splay树。红色是值。splay树的中序遍历就是dfs序,splay树上红色的两个维护的是子树内dep为奇和偶的点的异或和。

  有意义的点我打在左端点,右端点的值均为0。

  splay的时候upd一下把左右儿子的值跟自己异或一下就能维护那个异或和了。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
#define Maxn 400010 int n,Mod; int w[Maxn];
int nl[Maxn],nr[Maxn];
map<int,int> z; struct node
{
int x,y,next;
}t[Maxn*];
int len,first[Maxn];
void ins(int x,int y)
{
t[++len].x=x;t[len].y=y;
t[len].next=first[x];first[x]=len;
} struct sp
{
int son[],fa,d,a1,a2;
bool dep;
}tr[Maxn*];int tot; void upd(int x)
{
int lc=tr[x].son[],rc=tr[x].son[];
tr[x].a1=tr[lc].a1^tr[rc].a1;
tr[x].a2=tr[lc].a2^tr[rc].a2;
if(!tr[x].dep) tr[x].a2^=tr[x].d;
else tr[x].a1^=tr[x].d;
}
void rot(int x)
{
int fa=tr[x].fa,yy=tr[fa].fa;
int w=tr[fa].son[]==x?:;
tr[fa].son[-w]=tr[x].son[w];
if(tr[x].son[w]) tr[tr[x].son[w]].fa=fa;
if(yy)
{
if(tr[yy].son[]==fa) tr[yy].son[]=x;
else tr[yy].son[]=x;
}tr[x].fa=yy;
tr[x].son[w]=fa;tr[fa].fa=x;
upd(fa);upd(x);
}
void splay(int x,int nf)
{
while(tr[x].fa!=nf)
{
int fa=tr[x].fa,yy=tr[fa].fa;
if(yy==nf) rot(x);
else
{
if((tr[yy].son[]==fa)==(tr[fa].son[]==x)) {rot(fa);rot(x);}
else {rot(x);rot(x);}
}
}
}
int Lower(int x)
{
splay(x,);
x=tr[x].son[];
while(tr[x].son[]) x=tr[x].son[];
return x;
}
void insert(int fa,int x)
{
int r=Lower(fa);
splay(fa,);splay(r,fa);
tr[r].son[]=x;
tr[x].fa=r;
upd(r);upd(fa);
}
void dfs(int x,int fa)
{
tr[x].dep=!tr[fa].dep;
if(fa)
{
tr[nl[x]].son[]=nr[x];tr[nr[x]].fa=nl[x];
tr[nl[x]].d=w[x];upd(nr[x]);upd(nl[x]);
insert(fa,x);
}
for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa)
{
int y=t[i].y;
dfs(y,x);
}
} int main()
{
scanf("%d%d",&n,&Mod);Mod++;
for(int i=;i<=n;i++) {scanf("%d",&w[i]);z[i]=i;w[i]%=Mod;}
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y);ins(y,x);
}
for(int i=;i<=n;i++) nl[i]=i,nr[i]=i+n;tot=n*;
tr[].dep=;tr[].son[]=n+;
tr[].d=w[];tr[n+].fa=;upd(n+);upd();
dfs(,);
int q,nw=;
scanf("%d",&q);
while(q--)
{
int opt,ans;
int x,y,k;
scanf("%d",&opt);
if(opt==)
{
scanf("%d",&x);
x^=nw;
x=z[x];
splay(nl[x],);splay(nr[x],nl[x]);
if(!tr[x].dep) ans=tr[tr[nr[x]].son[]].a1;
else ans=tr[tr[nr[x]].son[]].a2;
if(ans==) printf("GTY\n");
else {printf("MeiZ\n");nw++;}
}
else if(opt==)
{
scanf("%d%d",&x,&y);
x^=nw;y^=nw;
y%=Mod;
x=z[x];
splay(nl[x],);
if(!tr[nl[x]].dep) tr[nl[x]].a2^=y^tr[nl[x]].d;
else tr[nl[x]].a1^=y^tr[nl[x]].d;
tr[nl[x]].d=y;
}
else
{
scanf("%d%d%d",&x,&y,&k);
x^=nw;y^=nw;k^=nw;
k%=Mod;x=z[x];z[y]=y=++n;
nl[y]=++tot;nr[y]=++tot;
tr[nl[y]].dep=!tr[nl[x]].dep;
tr[nl[y]].d=k;tr[nr[y]].d=;
tr[nr[y]].fa=nl[y];
tr[nl[y]].fa=nl[x];upd(nl[y]);upd(nr[y]);
insert(nl[x],nl[y]);
}
}
return ;
}

【AC了还是很兴奋的。。。以后要多做点dfs序,splay之类的。。

2017-03-30 16:39:42

【BZOJ 3729】3729: Gty的游戏 (Splay维护dfs序+博弈)的更多相关文章

  1. BZOJ 3729 splay维护DFS序+博弈论

    思路: 这像是 阶梯Nim之类的东西 我们 直接把sg函数 设成mod(L+1)的 一棵子树 向下的奇数层上的石子xor起来 就是答案 有加点和改值的操作 就splay维护一下 //By Sirius ...

  2. BZOJ3786 星系探索 【Splay维护dfs序】*

    BZOJ3786 星系探索 Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均 ...

  3. bzoj3786星系探索(splay维护dfs序)

    Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...

  4. 【BZOJ】3991: [SDOI2015]寻宝游戏 虚树+DFS序+set

    [题意]给定n个点的带边权树,对于树上存在的若干特殊点,要求任选一个点开始将所有特殊点走遍后返回.现在初始没有特殊点,m次操作每次增加或减少一个特殊点,求每次操作后的总代价.n,m<=10^5. ...

  5. BZOJ 4999 LCA树状数组差分维护DFS序

    Description 给一颗树,每个节点有个初始值 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x 2. Q i j x(0<=x<2 ...

  6. BZOJ3729Gty的游戏——阶梯博弈+巴什博弈+非旋转treap(平衡树动态维护dfs序)

    题目描述 某一天gty在与他的妹子玩游戏.妹子提出一个游戏,给定一棵有根树,每个节点有一些石子,每次可以将不多于L的石子移动到父节点,询问将某个节点的子树中的石子移动到这个节点先手是否有必胜策略.gt ...

  7. BZOJ 3881 [COCI2015]Divljak (Trie图+Fail树+树链的并+树状数组维护dfs序)

    题目大意: Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...

  8. BZOJ3159决战——树链剖分+非旋转treap(平衡树动态维护dfs序)

    题目描述 输入 第一行有三个整数N.M和R,分别表示树的节点数.指令和询问总数,以及X国的据点. 接下来N-1行,每行两个整数X和Y,表示Katharon国的一条道路. 接下来M行,每行描述一个指令或 ...

  9. CF877E Danil and a Part-time Job 线段树维护dfs序

    \(\color{#0066ff}{题目描述}\) 有一棵 n 个点的树,根结点为 1 号点,每个点的权值都是 1 或 0 共有 m 次操作,操作分为两种 get 询问一个点 x 的子树里有多少个 1 ...

随机推荐

  1. [php]referer应用--http防盗链技术

    1.防盗链的理解 所谓防盗链是防止其他的网站引用自己网站的资源连接,比如图片.视频等等,但是并不会阻碍从自己网站上享受资源的用户,这就要求能够将其他网站的连接请求阻止 2.防盗链的原理 其实从自己网站 ...

  2. 【BZOJ】2820: YY的GCD

    [题意]给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对.T<=10^4,N,M<=10^7. [算法]数论(莫比乌 ...

  3. 一般处理程序、ASP.NET核心知识(5)

    初窥 1.新建一个一般处理程序 新建一个一般处理程序 2.看看里头的代码 public class MyHandler : IHttpHandler { public void ProcessRequ ...

  4. Spring整合Quartz分布式调度

    前言 为了保证应用的高可用和高并发性,一般都会部署多个节点:对于定时任务,如果每个节点都执行自己的定时任务,一方面耗费了系统资源,另一方面有些任务多次执行,可能引发应用逻辑问题,所以需要一个分布式的调 ...

  5. NYOJ 228 士兵杀敌(五) (模拟)

    {题目链接](http://acm.nyist.net/JudgeOnline/problem.php?pid=228) 描述 南将军麾下有百万精兵,现已知共有M个士兵,编号为0~M,每次有任务的时候 ...

  6. 阿里Java研发工程师实习面经,附面试技巧

    作者:如何进阿里 链接:https://www.nowcoder.com/discuss/72899?type=0&order=0&pos=17&page=1 来源:牛客网 前 ...

  7. 浅谈iOS多线程

    浅谈iOS多线程 首先,先看看进程和线程的概念. 图1.1 这一块不难理解,重点点下他们的几个重要区别: 1,地址空间和资源:进程可以申请和拥有系统资源,线程不行.资源进程间相互独立,同一进程的各线程 ...

  8. python3.X和python2.7的区别

    1.python3.X将thread模块修改为_thread

  9. 三十分钟理解:线性插值,双线性插值Bilinear Interpolation算法

    线性插值 先讲一下线性插值:已知数据 (x0, y0) 与 (x1, y1),要计算 [x0, x1] 区间内某一位置 x 在直线上的y值(反过来也是一样,略): y−y0x−x0=y1−y0x1−x ...

  10. Android Debug Bridge (adb) device - no permissions

      I have a problem connecting HTC Wildfire A3333 in debugging mode with my Fedora Linux 17. Adb says ...