【bzoj2819】Nim(dfs序+树状数组/线段树)
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=2819
首先根据SG定理,可得若每堆石子数量的异或值为0,则后手必胜,反之先手必胜。于是我们就需要维护一个支持树上单点修改,树链查询异或值的数据结构。
首先我们可以用树链剖分解决。然而……蒟蒻我比较懒(既懒得写也懒得调),所以我们可以采取一种被用烂了的黑科技:dfs序。
首先我们会发现,我们可以把查询一条链拆成查询两个端点到根的链的异或值,以及lca的权值。这样一个点的权值修改,查询时只对他的子树有贡献。所以我们可以求出树的dfs序,然后把单点修改转为区间修改,把树链查询转化为单点查询。
然后为了代码方便,我们可以差分,把区间l~r修改转为修改l、r+1,查询单点k转化为查询1~k的异或值,就能用树状数组维护了。
代码:
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#define ll long long
#define ull unsigned long long
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define lowbit(x) (x& -x)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define eps 1e-18
#define maxn 500010
inline ll read()
{
ll tmp=; char c=getchar(),f=;
for(;c<''||''<c;c=getchar())if(c=='-')f=-;
for(;''<=c&&c<='';c=getchar())tmp=(tmp<<)+(tmp<<)+c-'';
return tmp*f;
}
struct edge{
int to,nxt;
}e[*maxn];
int fir[maxn],pos[maxn],l[maxn],r[maxn],val[maxn],vis[maxn],dep[maxn];
int fa[maxn][];
int bit[maxn];
int n,q,tot=,cnt=;
char op[];
void add(int x,int y){e[tot].to=y; e[tot].nxt=fir[x]; fir[x]=tot++;}
void dfs(int now)
{
vis[now]=; l[now]=pos[now]=++cnt;
for(int i=fir[now];~i;i=e[i].nxt)
if(!vis[e[i].to]){
fa[e[i].to][]=now; dep[e[i].to]=dep[now]+; dfs(e[i].to);
}
r[now]=cnt;
}
inline int getlca(int x,int y)
{
if(dep[x]<dep[y]){int tmp=x; x=y; y=tmp;}
int k=int(log(n)/log());
for(int i=k;i>=;i--)
if(dep[x]-(<<i)>=dep[y])x=fa[x][i];
if(x==y)return x;
for(int i=k;i>=;i--)
if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][];
}
void change(int x,int k){if(x>n)return; for(;x<=n;x+=lowbit(x))bit[x]^=k;}
int getxor(int x){int ans=; for(;x;x-=lowbit(x))ans^=bit[x]; return ans;}
int main()
{
memset(fir,,sizeof(fir));
int i,j;
n=read();
for(i=;i<=n;i++)val[i]=read();
for(i=;i<n;i++){
int x=read(),y=read(); add(x,y); add(y,x);
}
vis[]=; fa[][]=; dep[]=; dfs();
for(j=;<<j<=n;j++)
for(i=;i<=n;i++)
if(fa[i][j-])fa[i][j]=fa[fa[i][j-]][j-];
q=read();
for(i=;i<=n;i++)change(l[i],val[i]),change(r[i]+,val[i]);
for(i=;i<=q;i++){
scanf("%s",op);
if(op[]=='Q'){
int u=read(),v=read();
int tmp=getxor(pos[u])^getxor(pos[v])^val[getlca(u,v)];
if(tmp)printf("Yes\n"); else printf("No\n");
}
else{
int u=read(),k=read();
change(l[u],k^val[u]); change(r[u]+,k^val[u]); val[u]=k;
}
}
}
bzoj2819
虽然我用的是普通dfs,但是好像bzoj的栈空间挺大的,并不会爆。(不过还是哪天改个人工栈吧)
【bzoj2819】Nim(dfs序+树状数组/线段树)的更多相关文章
- 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树
正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...
- 树状数组 && 线段树应用 -- 求逆序数
参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...
- hdu1394(枚举/树状数组/线段树单点更新&区间求和)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给出一个循环数组,求其逆序对最少为多少: 思路:对于逆序对: 交换两个相邻数,逆序数 +1 ...
- hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu 5147 Sequence II【树状数组/线段树】
Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...
- POJ3321[苹果树] 树状数组/线段树 + dfs序
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions:39452 Accepted: 11694 Descr ...
- 【poj2182】【poj2828】树状数组/线段树经典模型:逆序查找-空位插入法
poj2182题意:有一个1~n的排列,现在给定每个人前面有多少个人的编号比他大,求这个排列是什么.n<=8000 poj2182题解: 逆序做,可以确定二分最后一个是什么,然后删除这个数.树状 ...
- HDU 5293 Train chain Problem - 树链剖分(树状数组) + 线段树+ 树型dp
传送门 题目大意: 一颗n个点的树,给出m条链,第i条链的权值是\(w_i\),可以选择若干条不相交的链,求最大权值和. 题目分析: 树型dp: dp[u][0]表示不经过u节点,其子树的最优值,dp ...
- [CSP-S模拟测试]:影魔(树状数组+线段树合并)
题目背景 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵魂,都有着自己 ...
随机推荐
- java API Runtime 启动进程
Runtime run = new Runtime.getRuntime(); Process p = run.exec("notepad.exe F:\\lesson\\a.java&qu ...
- Android开发:《Gradle Recipes for Android》阅读笔记(翻译)3.5——在flavors间合并java代码
问题: 你想要在单独的product flavors里面增加Acitivity或者其它java类. 解决方案: 创建合适的代码目录,增加java类,将它们和main代码合并. 讨论: flavors和 ...
- unintest基础1
import unittest class Testfunc(unittest.TestCase): def testfunc(self): print('testfunc1') def testfu ...
- 使用RestTemplate发送multipart/form-data格式的数据
现有业务场景需要使用RestTemplate发送一个post请求,请求格式为multipart/form-data的,可以使用以下方法: public Object sendRequest(Objec ...
- 锁(java, DB)
知识点 事务 锁(java, DB) 多线程知识点整理 锁(java, DB) 什么是锁 对资源的访问权限进行控制 如果把一个资源(对象)比喻成屋子.就好像你进入了屋子锁上了门.你家人和贼都进不去了. ...
- ECMAScript/JS 基础知识讲解
闭包 下面这个方法能输入0 1 2 ... 9吗?显然是不可以的,输出结果是10个10. function test() { var arr = []; for(var i = 0; i < 1 ...
- Quality of service
w https://en.wikipedia.org/wiki/Quality_of_service Quality of service (QoS) is the overall performan ...
- (4.4)dbcc checkdb 数据页修复
转自:http://blog.51cto.com/lzf328/955852 三篇 一.创建错误数据库 以前看Pual写过很多数据恢复的文章,他很多的测试都是自己创建的Corrupt数据库,其实我们自 ...
- 我的第四个Python小程序
简单的登陆程序: # Author: fansik # Description: Simply log in to small programs # Date: 2017/9/29 _username ...
- Nginx图片及样式文件不记录访问日志
1.Nginx作为web服务器是可直接在server配置文件中做如下配置: server { listen ; server_name www.fansik.com; access_log /data ...