https://www.lydsy.com/JudgeOnline/problem.php?id=2819

题意:树上单点修改及区间异或和查询。

思维难度不高,但是题比较硬核。

整体思路是维护每一个结点到根节点的距离。查询u,v树链上的异或和就是query(v) ^ query(u) ^ a[lca(u,v)],所以就要想办法维护树上的结点到根节点的异或和。

网上的题解大多是选择直接维护答案,修改的时候修改整颗子树的答案,用线段树或者树状数组区间异或一下l到r内的答案就可以。

我一开始没有想到直接上lca直接维护根节点的距离,所以在dfs序上见了一颗线段树,查询的时候query 1到u第一次出现地方的异或和,区间的时候常规单点修改也可过。

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
inline int read(){int now=;register char c=getchar();for(;!isdigit(c);c=getchar());
for(;isdigit(c);now=now*+c-'',c=getchar());return now;}
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
const double eps = 1e-;
const int maxn = 5e5 + ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ;
int N,M,K;
LL a[maxn];
struct Edge{
int next,to;
}edge[maxn * ];
int head[maxn],tot;
void init(){
for(int i = ; i <= N ; i ++) head[i] = -;
tot = ;
}
void add(int u,int v){
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
const int SP = ;
int pa[maxn][SP],dep[maxn];
//求dfs序
int num;
int dfs_index[maxn * ];
PII pos[maxn];
void dfs(int t,int la){
pa[t][] = la;
dep[t] = dep[la] + ;
for(int i = ; i <= SP - ; i ++) pa[t][i] = pa[pa[t][i - ]][i - ];
pos[t].fi = ++num;
dfs_index[num] = t;
for(int i = head[t]; ~i ; i = edge[i].next){
int v = edge[i].to;
if(v == la) continue;
dfs(v,t);
}
pos[t].se = ++num;
dfs_index[num] = t;
}
int lca(int u,int v){
if(dep[u] < dep[v]) swap(u,v);
int t = dep[u] - dep[v];
for(int i = ; i <= SP - ; i ++){
if(t & ( << i)) u = pa[u][i];
}
for(int i = SP - ; i >= ; i --){
int uu = pa[u][i],vv = pa[v][i];
if(uu != vv){
u = uu;
v = vv;
}
}
return u == v? u :pa[u][];
}
//线段树
struct Tree{
LL sum;
}tree[maxn << ];
void Pushup(int t){
tree[t].sum = tree[t << ].sum ^ tree[t << | ].sum;
}
void Build(int t,int l,int r){
if(l == r){
tree[t].sum = a[dfs_index[l]];
return;
}
int m = (l + r) >> ;
Build(t << ,l,m); Build(t << | ,m + ,r);
Pushup(t);
}
void update(int t,int p,int x,int L,int R){
if(L == R){
tree[t].sum = x;
return;
}
int m = (L + R) >> ;
if(p <= m) update(t << ,p,x,L,m);
else update(t << | ,p,x,m + ,R);
Pushup(t);
}
LL query(int t,int l,int r,int L,int R){
if(l <= L && R <= r){
return tree[t].sum;
}
int m = (L + R) >> ;
if(r <= m) return query(t << ,l,r,L,m);
else if(l > m) return query(t << | ,l,r,m + ,R);
else return query(t << ,l,m,L,m) ^ query(t << | ,m + ,r,m + ,R);
} LL query(int x){
return query(,,pos[x].fi,, * N);
}
int main(){
Sca(N); init();
For(i,,N) Scl(a[i]);
For(i,,N - ){
int u,v; Sca2(u,v);
add(u,v); add(v,u);
}
dfs(,);
Build(,, * N);
Sca(K);
while(K--){
char op[];
int u,v;
scanf("%s%d%d",op,&u,&v);
if(op[] == 'Q'){
if(query(u) ^ query(v) ^ a[lca(u,v)]) puts("Yes");
else puts("No");
}else{
update(,pos[u].fi,v,, * N);
update(,pos[u].se,v,, * N);
a[u] = v;
}
}
return ;
}

bzoj2819 DFS序 + LCA + 线段树的更多相关文章

  1. bzoj3306: 树(dfs序+倍增+线段树)

    比较傻逼的一道题... 显然求子树最小值就是求出dfs序用线段树维护嘛 换根的时候树的形态不会改变,所以我们可以根据相对于根的位置分类讨论. 如果询问的x是根就直接输出整棵树的最小值. 如果询问的x是 ...

  2. Codeforces 877E - Danil and a Part-time Job(dfs序+线段树)

    877E - Danil and a Part-time Job 思路:dfs序+线段树 dfs序:http://blog.csdn.net/qq_24489717/article/details/5 ...

  3. 用dfs序处理线段树的好题吗?

    https://www.cnblogs.com/mountaink/p/9878918.html 分析:每次的选取必须选最优的一条链,那我们考虑一下选择这条链后,把这条路上的点的权值更新掉,再采取选最 ...

  4. 7月13日考试 题解(DFS序+期望+线段树优化建图)

    T1 sign 题目大意:给出一棵 N 个节点的树,求所有起点为叶节点的有向路径,其 上每一条边权值和的和.N<=10000 水题.考试的时候毒瘤出题人(学长orz)把读入顺序改了一下,于是很多 ...

  5. hdu 3974 Assign the task(dfs序上线段树)

    Problem Description There is a company that has N employees(numbered from 1 to N),every employee in ...

  6. Luogu P2982 [USACO10FEB]慢下来 Slowing down | dfs序、线段树

    题目链接 题目大意: 有一棵N个结点树和N头奶牛,一开始所有奶牛都在一号结点,奶牛们将按从编号1到编号N的顺序依次前往自己的目的地,求每头奶牛在去往自己目的地的途中将会经过多少已经有奶牛的结点. 题解 ...

  7. Codeforces Round #200 (Div. 1) D. Water Tree(dfs序加线段树)

    思路: dfs序其实是很水的东西.  和树链剖分一样, 都是对树链的hash. 该题做法是:每次对子树全部赋值为1,对一个点赋值为0,查询子树最小值. 该题需要注意的是:当我们对一棵子树全都赋值为1的 ...

  8. hdu4366 Successor (dfs序+zkw线段树)

    Successor Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  9. URAL 1890 . Money out of Thin Air (dfs序hash + 线段树)

    题目链接: URAL 1890 . Money out of Thin Air 题目描述: 给出一个公司里面上司和下级的附属关系,还有每一个人的工资,然后有两种询问: 1:employee x y z ...

随机推荐

  1. MySQL字段属性NUll的注意点

    MySQL字段属性应该尽量设置为NOT NULL 除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL.这看起来好像有点争议,请往下看. 空值("&quo ...

  2. linux查找符合条件的文件并删除

    找到根目录下所有的以test开头的文件并把查找结果当做参数传给rm -rf命令进行删除: 1.find / -name “test*” |xargs rm -rf 2.find / -name “te ...

  3. hbase系列

    jvmhttps://www.cnblogs.com/jiyukai/p/6665199.html hbase https://blog.csdn.net/lizhitao/article/detai ...

  4. FPGA笔试题集锦(血的教训)

    1.名词解释: FPGA:现场可编程门阵列,一般工艺SRAM(易失性),所以要外挂配置芯片. CPLD:复杂可编程逻辑器件,一般工艺Flash(不易失). ASIC:专用集成电路 SOC:片上系统 S ...

  5. Linux iptables设置

    先举例子说明,若服务器网卡: eth0 10.10.0.100 eth0:0 10.10.0.200 eth0:1 10.10.0.201 eth0:2 10.10.0.202 只允许10.10.0. ...

  6. C#解决方案生成工具

    实验环境  VS2017 C# .NET4.6 项目都是.net framework框架 目的: 用程序生成解决方案和项目. 思路:手动建一个方案和项目,分析其中的文件内容,做成模板后,由程序调用.最 ...

  7. noiac132 B君的第三题 (树形dp)

    传送门 本来想用点分治做,结果root又求不对 算的时候还算错了 我好菜啊 结果szr大佬告诉我是树形dp 我好菜啊!! 我们有$\lceil \frac{x}{k} \rceil = \frac{x ...

  8. 解决忘记mysql中的root用户密码问题

    如果忘了数据库中的root密码,无法登陆mysql. 解决步骤: 1. 使用“--skip-grant-tables”启动数据库 ~]#systemctl stop mysql ~]#mysqld_s ...

  9. JetBrains全家桶破解思路(最新更新:2019-04-17)

    JetBrains全家桶破解思路(以DataGrip为例) 2019-04-17 add new key 2019-01-24 add new key and code 2018-12-24 add ...

  10. Why I don't want use JPA anymore

    转自:https://dev.to/alagrede/why-i-dont-want-use-jpa-anymore-fl Great words for what is considered by ...