题目

著名游戏设计师vfleaking,最近迷上了Nim。普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取。谁不能取谁输。这个游戏是有必胜策略的。于是vfleaking决定写一个玩Nim游戏的平台来坑玩家。

为了设计漂亮一点的初始局面,vfleaking用以下方式来找灵感:拿出很多石子,把它们聚成一堆一堆的,对每一堆编号1,2,3,4,…n,在堆与堆间连边,没有自环与重边,从任意堆到任意堆都只有唯一一条路径可到达。然后他不停地进行如下操作:

1.随机选两个堆v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略,如果有,vfleaking将会考虑将这些石子堆作为初始局面之一,用来坑玩家。

2.把堆v中的石子数变为k。

由于vfleaking太懒了,他懒得自己动手了。请写个程序帮帮他吧。

输入格式

第一行一个数n,表示有多少堆石子。

接下来的一行,第i个数表示第i堆里有多少石子。

接下来n-1行,每行两个数v,u,代表v,u间有一条边直接相连。

接下来一个数q,代表操作的个数。

接下来q行,每行开始有一个字符:

如果是Q,那么后面有两个数v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略。

如果是C,那么后面有两个数v,k,代表把堆v中的石子数变为k。

对于100%的数据:

1≤N≤500000, 1≤Q≤500000, 0≤任何时候每堆石子的个数≤32767

其中有30%的数据:

石子堆组成了一条链,这3个点会导致你DFS时爆栈(也许你不用DFS?)。其它的数据DFS目测不会爆。

注意:石子数的范围是0到INT_MAX

输出格式

对于每个Q,输出一行Yes或No,代表对询问的回答。

输入样例

5

1 3 5 2 5

1 5

3 5

2 5

1 4

6

Q 1 2

Q 3 5

C 3 7

Q 1 2

Q 2 4

Q 5 3

输出样例

Yes

No

Yes

Yes

Yes

题解

14s,还以为要T了QAQ

额。其实和博弈论是有那么点关系的。。其实就是一个众所周知博弈论结论:

Nim游戏先手必胜,当且仅当石子数的异或和不为0

说白了就是维护路径异或和

树剖?应该可以吧。。。【题目说会爆栈?】

我选择了求dfs序【然而还是要dfs。。】

我们开一棵线段树维护每个dfs序对应点到根的异或和

询问 询问u和v对应的异或和,再异或上lca的权值

修改 一个点的权值修改,只会影响到其子树,利用dfn就可以在线段树上修改

复杂度O(nlogn)

常数大得飞起

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u]; k != -1; k = ed[k].nxt)
using namespace std;
const int maxn = 500005,maxm = 1000005,INF = 1000000000;
inline int RD(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}
return out * flag;
}
int h[maxn],ne = 0;
struct EDGE{int to,nxt;}ed[maxm];
inline void build(int u,int v){
ed[ne] = (EDGE){v,h[u]}; h[u] = ne++;
ed[ne] = (EDGE){u,h[v]}; h[v] = ne++;
}
int dfn[maxn],fa[maxn][20],siz[maxn],dep[maxn],V[maxn],w[maxn],id[maxn],n,cnt = 0;
void dfs(int u){
dfn[u] = ++cnt; siz[u] = 1; id[cnt] = u;
REP(i,19) fa[u][i] = fa[fa[u][i - 1]][i - 1];
Redge(u) if (ed[k].to != fa[u][0]){
fa[ed[k].to][0] = u; dep[ed[k].to] = dep[u] + 1; w[ed[k].to] ^= w[u];
dfs(ed[k].to);
siz[u] += siz[ed[k].to];
}
}
int sum[4 * maxn],lazy[4 * maxn],L,R;
inline void Build(int u,int l,int r){
if (l == r) {sum[u] = w[id[l]]; return;}
int mid = l + r >> 1;
Build(u << 1,l,mid);
Build(u << 1 | 1,mid + 1,r);
sum[u] = sum[u << 1] ^ sum[u << 1 | 1];
}
inline void pd(int u,int l,int r){
int mid = l + r >> 1;
sum[u << 1] ^= ((mid - l + 1) & 1) * lazy[u];
sum[u << 1 | 1] ^= ((r - mid) & 1) * lazy[u];
lazy[u << 1] ^= lazy[u]; lazy[u << 1 | 1] ^= lazy[u];
lazy[u] = 0;
}
void modify(int u,int l,int r,int v){
if (l >= L && r <= R) {sum[u] ^= ((r - l + 1) & 1) * v; lazy[u] ^= v; return;}
if (lazy[u]) pd(u,l,r);
int mid = l + r >> 1;
if (mid >= L) modify(u << 1,l,mid,v);
if (mid < R) modify(u << 1 | 1,mid + 1,r,v);
sum[u] = sum[u << 1] ^ sum[u << 1 | 1];
}
int query(int u,int l,int r){
if (l >= L && r <= R) return sum[u];
if (lazy[u]) pd(u,l,r);
int mid = l + r >> 1;
if (mid >= R) return query(u << 1,l,mid);
else if (mid < L) return query(u << 1 | 1,mid + 1,r);
else return query(u << 1,l,mid) + query(u << 1 | 1,mid + 1,r);
}
int lca(int u,int v){
if (dep[u] < dep[v]) swap(u,v);
int d = dep[u] - dep[v];
for (int i = 0; (1 << i) <= d; i++)
if ((1 << i) & d) u = fa[u][i];
if (u == v) return u;
for (int i = 19; i >= 0; i--)
if (fa[u][i] != fa[v][i]) u = fa[u][i],v = fa[v][i];
return fa[u][0];
}
void Query(int u,int v){
int a,b,c;
L = R = dfn[u]; a = query(1,1,n);
L = R = dfn[v]; b = query(1,1,n);
c = V[lca(u,v)];
if (a ^ b ^ c) puts("Yes");
else puts("No");
}
void Change(int u,int v){
L = dfn[u]; R = dfn[u] + siz[u] - 1;
modify(1,1,n,V[u] ^ v); V[u] = v;
}
int main(){
memset(h,-1,sizeof(h));
n = RD();
REP(i,n) w[i] = V[i] = RD();
REP(i,n - 1) build(RD(),RD());
dep[1] = 1; dfs(1);
Build(1,1,n);
int Q = RD(),u,v; char cmd;
while (Q--){
cmd = getchar();
while (cmd != 'Q' && cmd != 'C') cmd = getchar();
u = RD(); v = RD();
if (cmd == 'Q') Query(u,v);
else Change(u,v);
}
return 0;
}

BZOJ2819 Nim 【dfn序 + lca + 博弈论】的更多相关文章

  1. bzoj 2819 Nim dfn序+树状数组维护区间异或值

    题目大意 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...

  2. 洛谷P3703 [SDOI2017]树点涂色(LCT,dfn序,线段树,倍增LCA)

    洛谷题目传送门 闲话 这是所有LCT题目中的一个异类. 之所以认为是LCT题目,是因为本题思路的瓶颈就在于如何去维护同颜色的点的集合. 只不过做着做着,感觉后来的思路(dfn序,线段树,LCA)似乎要 ...

  3. Kattis - boxes (dfn序)

    Boxes There are N boxes, indexed by a number from 1 to N . Each box may (or not may not) be put into ...

  4. BZOJ 4999: This Problem Is Too Simple! DFS序+LCA+树状数组+离线

    Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) , ...

  5. [jzoj5786]【NOIP2008模拟】观察 (dfs序+lca)

    传送门 Description infleaking十分愉快地走在路上, 因为经过10^9^9^9年后, 他得到了一个新技能--观察大法. 刚出来的infleaking就想要挑战自我. 为什么infl ...

  6. 51nod 1576 Tree and permutation(树的重心+dfn序)

    乍一看我不会. 先不考虑加点. 先考虑没有那个除\(2\). 考虑每一条边的贡献,假设某一条边把这棵树分成大小为x,y的两个部分. 那么这条边最多可以被使用\(min(x,y)*2\)次(因为有进有出 ...

  7. 洛谷P4689 [Ynoi2016]这是我自己的发明(莫队,树的dfn序,map,容斥原理)

    洛谷题目传送门 具体思路看别的题解吧.这里只提两个可能对常数和代码长度有优化的处理方法. I 把一个询问拆成\(9\)个甚至\(16\)个莫队询问实在是有点珂怕. 发现询问的一边要么是一个区间,要么是 ...

  8. 线段树分治总结(线段树分治,线段树,并查集,树的dfn序,二分图染色)

    闲话 stO猫锟学长,满脑子神仙DS 网上有不少Dalao把线段树分治也归入CDQ分治? 还是听听YCB巨佬的介绍: 狭义:只计算左边对右边的贡献. 广义:只计算外部对内部的贡献. 看来可以理解为广义 ...

  9. 树的遍历顺序 - dfs序|欧拉序|dfn序(备忘)

    (仅作备忘) dfs序是dfs过程中对于某节点进入这个节点的子树和离开子树的顺序 满足每个节点都会在dfs序上出现恰好两次 任意子树的dfs序都是连续的 欧拉序是dfs过程中经过节点的顺序 每个节点至 ...

随机推荐

  1. ZooKeeper(3)-内部原理

    一. 节点类型 二. Stat结构体 1)czxid-创建节点的事务zxid 每次修改ZooKeeper状态都会收到一个zxid形式的时间戳,也就是ZooKeeper事务ID. 事务ID是ZooKee ...

  2. 03---Nginx配置文件

    #启动子进程程序默认用户#user nobody;#一个主进程和多个工作进程.工作进程是单进程的,且不需要特殊授权即可运行:这里定义的是工作进程数量worker_processes 1; #全局错误日 ...

  3. AtCoder AGC028-F:Reachable Cells

    越来越喜欢AtCoder了,遍地都是神仙题. 题意: 给定一个\(N\)行\(N\)列的迷宫,每一个格子要么是障碍,要么是空地.每一块空地写着一个数码.在迷宫中,每一步只允许向右.向下走,且只能经过空 ...

  4. ABAP CDS ON HANA-(4)ヘッダー行編集

    Explicit Name List use in CDS We create a simple  CDS View like below. @AbapCatalog.sqlViewName: ‘ZS ...

  5. Spring 中的文件上传与下载控制

    先创建根应用上下文配置,WebDemo/src/main/java/com/seliote/webdemo/config/RootContextConfig.java package com.seli ...

  6. python基础集结号

    Python 号称是最接近人工智能的语言,因为它的动态便捷性和灵活的三方扩展,成就了它在人工智能领域的丰碑 走进Python,靠近人工智能 一.编程语言Python的基础 之 "浅入浅出&q ...

  7. leetcode笔记--2 reverse string

    my answer: 出错点:new_list[s] = list_s[u-1-s] 这样会出错, 重点:(1) map(str, s) 函数的使用,例:ls = [1,2,3]rs = map(st ...

  8. 事务消息中心-TMC

    此文已由作者杨凯明授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 背景 为什么要做事务消息中心 原有kqueue的方式缺点: 降低业务库性能 占用业务库磁盘 历史数据管理成本 ...

  9. 『Python Kivy』官方乒乓球游戏示例解析

    本篇文章用于对Kivy框架官方所给出的一个「乒乓球」小游戏的源码进行简单地解析.我会尽可能的将方方面面的内容都说清楚.在文章的最下方为官方所给出的这个小游戏的教程以及游戏源码. 由于篇幅所限,本文只简 ...

  10. 小程序如何去掉button组件的边框

    小程序获取用户授权不再支持wx.getUserInfo方法,改为用button获取,格式如下 <button class="btn btn" open-type=" ...