Problem Description
Dylans is given a tree with
N
nodes.



All nodes have a value A[i].Nodes
on tree is numbered by 1∼N.



Then he is given Q
questions like that:



①0 x y:change
node x′s
value to y



②1 x y:For
all the value in the path from x
to y,do
they all appear even times?



For each ② question,it guarantees that there is at most one value that appears odd times on the path.



1≤N,Q≤100000,
the value A[i]∈N
and A[i]≤100000
 
Input
In the first line there is a test number
T.

(T≤3
and there is at most one testcase that N>1000)



For each testcase:



In the first line there are two numbers N
and Q.



Then in the next N−1
lines there are pairs of (X,Y)
that stand for a road from x
to y.



Then in the next line there are N
numbers A1..AN
stand for value.



In the next Q
lines there are three numbers(opt,x,y).
 
Output
For each question ② in each testcase,if the value all appear even times output "-1",otherwise output the value that appears odd times.
 
Sample Input
1
3 2
1 2
2 3
1 1 1
1 1 2
1 1 3
 
Sample Output
-1
1
Hint
If you want to hack someone,N and Q in your testdata must smaller than 10000,and you shouldn't print any space in each end of the line.
 
Source
 

大致题意:

一棵树1e5节点的树。有1e5次两种操作。改动某点的权值,询问两点间的路径上的每一个权值是否都是偶数个,若不是输出奇数个的权值大小。保证询问的路径上最多仅仅有一个权值是奇数个

思路:

方法1.维护每一个点到根的异或,然后查询就是xor[u]^xor[v]^LCA(u,v)

更新操作:更新某个点显然此点的子树的xor到根的异或都会更新。所以用dfs记录进入节点和退出节点的时间戳,把时间戳作为节点映射到线段树上(所以个数是数节点的两倍),然后成段更新进入此节点到退出此节点的时间戳的区间就可以

复杂度是nlogn

方法2:

正面上。询问就是两个点间的路径的异或,即树链剖分

复杂度n*logn*logn

方法一:

#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <cstdio>
#include <ctime>
#include <bitset>
#include <algorithm>
#define SZ(x) ((int)(x).size())
#define ALL(v) (v).begin(), (v).end()
#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)
#define REP(i,n) for ( int i=1; i<=int(n); i++ )
using namespace std;
typedef long long ll; const int N = 1e5+100;
int n,Q;
int indx;
struct Edge
{
int v,nxt;
Edge(){}
Edge(int v,int nxt):v(v),nxt(nxt){}
}es[N<<1];
int head[N],ecnt;
inline void add_edge(int v,int u)
{
es[ecnt] = Edge(v,head[u]);
head[u] = ecnt++;
es[ecnt] = Edge(u,head[v]);
head[v] = ecnt++;
}
int val[N];
//....................................
#define root 1,indx,1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int XOR[N<<2];
inline void pushup(int rt)
{
XOR[rt] = XOR[rt<<1]^XOR[rt<<1|1];
}
void update(int pos,int x,int l,int r,int rt)
{
if(l == r)
{
XOR[rt] ^= x;
return ;
}
int m = (l+r)>>1;
if(pos <= m) update(pos,x,lson);
else update(pos,x,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L <= l && r <= R) return XOR[rt];
int m = (l+r)>>1;
int ans = 0;
if(L <= m) ans ^= query(L,R,lson);
if(R > m) ans ^= query(L,R,rson);
return ans;
}
//.................................
int dep[N],hvyson[N],sz[N],fa[N];
void dfs1(int u)
{
dep[u] = dep[fa[u]]+1;
hvyson[u] = 0,sz[u] = 1;
for(int i = head[u];~i;i = es[i].nxt)
{
int v = es[i].v;
if(v == fa[u]) continue;
fa[v] = u;
dfs1(v);
sz[u] += sz[v];
if(sz[v] > sz[hvyson[u]]) hvyson[u] = v;
}
}
int tp[N],tid[N];
void dfs2(int u,int ance)
{
tid[u] = ++indx;
tp[u] = ance;
if(hvyson[u]) dfs2(hvyson[u],ance);
for(int i = head[u];~i;i = es[i].nxt)
{
int v = es[i].v;
if(v == fa[u]) continue;
if(v != hvyson[u])dfs2(v,v);
}
}
int ask(int u,int v)
{
int anceu = tp[u],ancev = tp[v];
int ans = 0;
while(anceu != ancev)
{
if(dep[anceu] < dep[ancev]) swap(anceu,ancev),swap(u,v);
ans ^= query(tid[anceu],tid[u],root);
u = fa[anceu];
anceu = tp[u];
}
if(u == v) return ans ^= val[u];
if(dep[u] < dep[v]) return ans ^= query(tid[u],tid[v],root);
else return ans ^= query(tid[v],tid[u],root);
}
//..................................
void ini()
{
ecnt = indx = 0;
memset(head,-1,sizeof(head));
memset(XOR,0,sizeof(XOR));
}
int main()
{ int T;
scanf("%d",&T);
while(T--)
{
ini();
scanf("%d%d",&n,&Q);
REP(i,n-1)
{
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v);
}
REP(i,n) scanf("%d",&val[i]),val[i]++;
dfs1(1);
dfs2(1,1);
REP(i,n) update(tid[i],val[i],root);
REP(i,Q)
{
int op;
scanf("%d",&op);
if(op == 0)
{
int u,x;
scanf("%d%d",&u,&x);x++;
update(tid[u],val[u]^x,root);
val[u] = x;
}
else
{
int u,v;
scanf("%d%d",&u,&v);
printf("%d\n",ask(u,v)-1);
}
}
}
}

方法二:

//312MS 21660K 4306 B C++
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <cstdio>
#include <ctime>
#include <bitset>
#include <algorithm>
#define SZ(x) ((int)(x).size())
#define ALL(v) (v).begin(), (v).end()
#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)
#define REP(i,n) for ( int i=1; i<=int(n); i++ )
using namespace std;
typedef long long ll; const int N = 1e5+100;
int n,Q;
struct Edge
{
int v,nxt;
Edge(){}
Edge(int v,int nxt) : v(v),nxt(nxt){}
}es[N*2];
int ecnt,head[N];
inline void add_edge(int u,int v)
{
es[ecnt] = Edge(v,head[u]);
head[u] = ecnt++;
es[ecnt] = Edge(u,head[v]);
head[v] = ecnt++;
}
int val[N];
//................................... int indx,st[N],ed[N],vs[N<<1];
int dp[N];
void dfs(int u,int fa)
{
dp[u] = dp[fa]^val[u];
st[u] = ++indx;
vs[indx] = u;
for(int i = head[u];~i;i = es[i].nxt)
{
int v = es[i].v;
if(v == fa) continue;
dfs(v,u);
}
ed[u] = ++indx;
vs[indx] = u;
} //............................... int dep[N];
bool vis[N];
int pa[N][20];
void bfs()
{
queue<int>q;
q.push(1);
pa[1][0]=1;
vis[1]=1;
while(!q.empty())
{
int u=q.front(); q.pop();
for(int i=1;i<20;i++) pa[u][i]=pa[pa[u][i-1]][i-1];
for(int i=head[u];~i;i=es[i].nxt)
{
int v=es[i].v;
if(vis[v]==0)
{
vis[v]=1;
pa[v][0]=u;
dep[v]=dep[u]+1;
q.push(v);
}
}
}
} int LCA(int u,int v)
{
if(dep[u]>dep[v]) swap(u,v);
for(int det=dep[v]-dep[u],i=0;det;i++,det>>=1)
if(det&1) v=pa[v][i];
if(v==u) return v;
for(int i=20-1;i>=0;i--)
if(pa[u][i]!=pa[v][i]) v=pa[v][i],u=pa[u][i];
return pa[u][0];
}
//...............................
int XOR[(N<<1)<<2],col[(N<<1)<<2];
#define root 1,indx,1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 inline void pushup(int rt)
{
XOR[rt] = XOR[rt<<1]^XOR[rt<<1|1];
}
inline void pushdown(int rt)
{
if(col[rt] == 0) return ;
col[rt<<1] ^= col[rt];
col[rt<<1|1] ^= col[rt];
XOR[rt<<1] ^= col[rt];
XOR[rt<<1|1] ^= col[rt];
col[rt] = 0;
}
void build(int l,int r,int rt)
{
if(l == r)
{
XOR[rt] = dp[vs[l]];
col[rt] = 0;
return ;
}
int m = (l+r)>>1;
build(lson);
build(rson);
pushup(rt);
} void update(int L,int R,int x,int l,int r,int rt)
{
if(L <= l && r <= R)
{
XOR[rt] ^= x;
col[rt] ^= x;
return ;
}
pushdown(rt);
int m = (l+r)>>1;
if(L <= m) update(L,R,x,lson);
if(R > m) update(L,R,x,rson);
pushup(rt);
}
int query(int pos,int l,int r,int rt)
{
if(l == r) return XOR[rt];
pushdown(rt);
int m = (l+r)>>1;
if(pos <= m) return query(pos,lson);
else return query(pos,rson);
}
//..............................
void ini()
{
indx = ecnt = 0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ini();
scanf("%d%d",&n,&Q);
REP(i,n-1)
{
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v);
}
REP(i,n) scanf("%d",&val[i]),val[i]++;
dfs(1,0);
bfs();
build(root);
while(Q--)
{
int op;
scanf("%d",&op);
if(op == 0)
{
int u,x;
scanf("%d%d",&u,&x);
x++;
update(st[u],ed[u],val[u]^x,root);
val[u] = x;
}
else
{
int u,v;
scanf("%d%d",&u,&v);
int ans = query(ed[u],root)^query(ed[v],root)^val[LCA(u,v)];
printf("%d\n",ans-1);
}
}
}
}

HDU 5274 Dylans loves tree(LCA+dfs时间戳+成段更新 OR 树链剖分+单点更新)的更多相关文章

  1. hdu 5274 Dylans loves tree(LCA + 线段树)

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  2. Hdu 5274 Dylans loves tree (树链剖分模板)

    Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...

  3. hdu 5274 Dylans loves tree

    Dylans loves tree http://acm.hdu.edu.cn/showproblem.php?pid=5274 Time Limit: 2000/1000 MS (Java/Othe ...

  4. HDU 5274 Dylans loves tree 树链剖分+线段树

    Dylans loves tree Problem Description Dylans is given a tree with N nodes. All nodes have a value A[ ...

  5. HDU 5274 Dylans loves tree(树链剖分)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5274 [题目大意] 给出一棵树,每个点有一个权值,权值可修改,且大于等于0,询问链上出现次数为奇数 ...

  6. hdu 5274 Dylans loves tree (树链剖分 + 线段树 异或)

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  7. hdu Dylans loves tree [LCA] (树链剖分)

    Dylans loves tree view code#pragma comment(linker, "/STACK:1024000000,1024000000") #includ ...

  8. BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )

    做一次MST, 枚举不在最小生成树上的每一条边(u,v), 然后加上这条边, 删掉(u,v)上的最大边(或严格次大边), 更新答案. 树链剖分然后ST维护最大值和严格次大值..倍增也是可以的... - ...

  9. AC日记——Dylans loves tree hdu 5274

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

随机推荐

  1. PAT Basic 1033

    1033 旧键盘打字 旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现.现在给出应该输入的一段文字.以及坏掉的那些键,打出的结果文字会是怎样? 输入格式: 输入在 2 行中分别给出坏掉 ...

  2. SQLServer数据库查看死锁、堵塞情况

    在压力测试过程中,不间断的按F5键执行上面的SQL语句,如果出现死锁或者堵塞现象,就会在执行结果中罗列出来.如果每次连续执行SQL,都有死锁或者堵塞出现,说明死锁或者堵塞的比较严重. --每秒死锁数量 ...

  3. 关于logging模块重复问题

    logger对象配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import logging # 获取一个新日志logger = ...

  4. Java-获取堆的大小

    package com.tj; public class getHeapInfo { public static void main(String[] args) { //获取当前堆的大小 byte ...

  5. Python第三方库之openpyxl(11)

    Python第三方库之openpyxl(11) Stock Charts(股票图) 在工作表上按特定顺序排列的列或行中的数据可以在股票图表中绘制.正如其名称所暗示的,股票图表通常被用来说明股价的波动. ...

  6. “玲珑杯”ACM比赛 Round #11 " ---1097 - 萌萌哒的第二题

    1097 - 萌萌哒的第二题 题意:中文题好像没有必要说题意了吧.. 思路:我们知道由于运输桥不能交叉,所以从右往左所修建的桥的序号是严格单增的.但是每个工厂B有6种选择,只能选一个求最多能建造几座桥 ...

  7. 【单调队列】bzoj 1407 [HAOI2007]理想的正方形

    [题意] 给定一个n*m的矩阵,求所有大小为k*k的正方形中(最大值-最小值)的最小值 [思路] 先横着算出每一行的长度为k的窗口内的最大值,变成一个n*(m-k+1)的矩阵mx 再竖着算出每一列的长 ...

  8. 【THUSC2016】成绩单(bzoj4897)

    $f(i,j,x,y)$ 表示区间 $[i,j]$中,第 $j$ 个数在最后一次操作中才消去,最后一次操作的最大值为 $x$,最小值为 $y$ 时的最小代价: $g(i,j)$ 表示区间 $[i,j] ...

  9. Wiley出版 SQL Server 2005宝典

    原文发布时间为:2008-07-30 -- 来源于本人的百度文章 [由搬家工具导入] Wiley出版 SQL Server 2005宝典 迅雷专用高速下载    thunder://QUFmdHA6L ...

  10. jquery的固定定位效果

    今天做了个固定定位的效果.比如对导航需要进行固定定位效果: 当没有滚动到导航下面,导航正常显示. 当滚动到导航下面,导航就固定到顶部. 这个效果使用了jquery的方法实现,具体思路为: 1)首先获取 ...