bzoj 2819: Nim 树状数组+dfs序
来源:互联网 发布:淘宝定做衣服 编辑:程序博客网 时间:2024/05/16 03:03
题意
给一棵树,要求资辞两个操作:
Q x y询问x到y路径上的异或和是否为0.
C x y将x的权值改为y
n,q<=500000
分析
这题一眼过去的想法就是树剖嘛,结果log2发现会爆炸。。。
其实我们只要维护每个点到根的路径异或和就好了。
那么考虑每修改一个点会影响到哪些点,显然就是它子树内的点啦!
那么我们只要用dfs序或树剖序,然后每次修改的时候用树状数组差分一下就好啦。
我打的是树剖,因为我觉得树剖不仅空间更棒棒,而且求lca也很方便啊。
顺便说一句,bzoj貌似是linux下评测,所以是不会爆栈哒。
代码
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;const int N=500005;int n,q,cnt,last[N],a[N],size[N],top[N],fa[N],mn[N],mx[N],dep[N],sz,c[N];struct edge{int to,next;}e[N*2];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;}void addedge(int u,int v){ e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt; e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt;}void dfs1(int x){ dep[x]=dep[fa[x]]+1;size[x]=1; for (int i=last[x];i;i=e[i].next) { if (e[i].to==fa[x]) continue; fa[e[i].to]=x; dfs1(e[i].to); size[x]+=size[e[i].to]; }}void dfs2(int x,int chain){ mn[x]=mx[x]=++sz;top[x]=chain;int k=0; for (int i=last[x];i;i=e[i].next) if (e[i].to!=fa[x]&&size[e[i].to]>size[k]) k=e[i].to; if (!k) return; dfs2(k,chain); for (int i=last[x];i;i=e[i].next) if (e[i].to!=fa[x]&&e[i].to!=k) dfs2(e[i].to,e[i].to); mx[x]=sz;}int get_lca(int x,int y){ while (top[x]!=top[y]) { if (dep[top[x]]<dep[top[y]]) swap(x,y); x=fa[top[x]]; } if (dep[x]<dep[y]) return x; else return y;}void ins(int x,int y){ while (x<=n) { c[x]^=y; x+=x&(-x); }}int query(int x){ int ans=0; while (x) { ans^=c[x]; x-=x&(-x); } return ans;}int main(){ n=read(); for (int i=1;i<=n;i++) a[i]=read(); for (int i=1;i<n;i++) { int x=read(),y=read(); addedge(x,y); } dfs1(1); dfs2(1,1); for (int i=1;i<=n;i++) ins(mn[i],a[i]),ins(mx[i]+1,a[i]); q=read(); while (q--) { char ch[2]; scanf("%s",ch); if (ch[0]=='Q') { int x=read(),y=read(),lca=get_lca(x,y); if (query(mn[x])^query(mn[y])^a[lca]) puts("Yes"); else puts("No"); } else { int x=read(),y=read(); ins(mn[x],a[x]);ins(mx[x]+1,a[x]); a[x]=y; ins(mn[x],y);ins(mx[x]+1,y); } } return 0;}
阅读全文
0 0
- bzoj 2819: Nim 树状数组+dfs序
- BZOJ 2819 Nim 树链剖分/DFS序+LCA+树状数组
- [BZOJ 2819]nim(DFS序+树状数组+SG博弈)
- BZOJ 2819: Nim 树状数组+lca+dfs序
- [BZOJ2819] Nim && dfs序 + 树状数组 + LCA
- BZOJ2819 Nim(dfs序+树状数组)
- [BZOJ2819]Nim-树状数组-dfs序
- bzoj 1103(DFS序+树状数组)
- [LCA][dfs序]BZOJ 2819: Nim
- [dfs序 树状数组] BZOJ 4034 [HAOI2015]T2
- [dfs序 树状数组] BZOJ 1103 [POI2007]大都市meg
- 【bzoj 1103】[POI2007]大都市meg 树状数组维护dfs序
- BZOJ 1103: [POI2007]大都市meg 树链剖分, 树状数组+DFS序
- [bzoj 1103] 大都市meg(树状数组和dfs序)
- [BZOJ]1103: [POI2007]大都市meg dfs序+树状数组
- BZOJ 1103 [POI 2007] dfs序+树状数组 解题报告
- dfs序+树状数组
- BZOJ 1103 大都市(DFS序+树状数组+差分数组/树链剖分)
- 使用 Comparable 接口实现对象的属性排序
- forward(转发)和redirect(重定向)的区别
- hrbust 2256 南西群岛海域·冲之岛近海(暴力)
- 动态调用action
- Python 字典
- bzoj 2819: Nim 树状数组+dfs序
- HDU 1426 Sudoku Killer (解数独) 一个令人呕吐的 代码
- 虚幻4C++编程入门深入了解
- java之拦截器的配置
- Idea快捷键
- iOS逆向工程之Theos
- 2014年第五届蓝桥杯C/C++程序设计本科B组决赛 生物芯片(编程大题)
- 封装 继承 抽象类和接口的理解
- 终端命令别名设置