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 xs
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. vmware 装 puppy

    说做就做了,但是开始怎么试都没装成功,后来在网上查了些资料,再结合自己的实践,终于成功了.下面我就把如何让Puppy Linux安装到VMware 硬盘上一步一步奉献给大家. 一.准备 1.1 安装好 ...

  2. 关于Powershell执行时的问题

    问题1: [问题描述] 使用Invoke-Command命令登录远程主机执行命令时,提示如下错误: [192.168.1.135] 连接到远程服务器失败,错误消息如下: WinRM 客户端无法处理该请 ...

  3. luogu3759 [TJOI2017]不勤劳的图书管理员

    分块+权值逆序对 #include <algorithm> #include <iostream> #include <cstdio> #include <c ...

  4. Leetcode 357.计算各个位数不同的数字个数

    计算各个位数不同的数字个数 给定一个非负整数 n,计算各位数字都不同的数字 x 的个数,其中 0 ≤ x < 10n . 示例: 输入: 2 输出: 91 解释: 答案应为除去 11,22,33 ...

  5. Leetcode 354.俄罗斯套娃信封问题

    俄罗斯套娃信封问题 给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h) 出现.当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样. 请计 ...

  6. Codeforces Round #417 (Div. 2) 花式被虐

    A. Sagheer and Crossroads time limit per test 1 second memory limit per test 256 megabytes input sta ...

  7. nginx报错502

    http请求流程:一般情况下,提交动态请求的时候,nginx会直接把 请求转交给php-fpm,而php-fpm再分配php-cgi进程来处理相关的请求,之后再依次返回,最后由nginx把结果反馈给客 ...

  8. 【DFS序+线段树区间更新区间求最值】HDU 5692 Snacks

    http://acm.hdu.edu.cn/showproblem.php?pid=5692 [思路] 每更新一个点,子树的所有结点都要更新,所以是区间更新 每查询一个点,子树的所有结点都要查询,所以 ...

  9. Honey Heist

    5092: Honey Heist 时间限制: 1 Sec  内存限制: 128 MB 题目描述 0x67 is a scout ant searching for food and discover ...

  10. 小Z的袜子(bzoj 2038)

    Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把这N只袜 ...