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

时间:2022-09-04 11:34:15

Dylans loves tree

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1444    Accepted Submission(s): 329

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
 
/*
hdu 5274 Dylans loves tree(LCA + 线段树) problem:
给你有一个树,然后有两个操作
1.修改第x个节点的值为y
2.查询x~y路径上哪一个数出现了奇数次 solve:
最开始想的就是通过异或求,但是不知道应该怎么保存 各个数各自出现了多少次
后来发现别人都是用的异或和来求,如果xor[x]表示x到根节点所有的异或和,由于题目保证只可能有一个数出现奇数次
那么
xor[a]^xor[b]^xor[lca(a,b)]
就等于求的那个(出现偶数次的都被抵消了) 然后就是怎么修改值了,如果修改了一个节点的值只会对以这个节点为根的树造成影响。所以可以通过dfs序转换到
线段树上进行区间修改 hhh-2016-08-09 15:12:07
*/
#pragma comment(linker,"/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#include <map>
#include <queue>
#include <vector>
#include <set>
#define lson (i<<1)
#define rson ((i<<1)|1)
using namespace std;
typedef long long ll;
const int maxn=100000 + 500;
const int INF=0x3f3f3f3f;
const int mod = 1e9+7;
int n,tot,cnt;
int head[maxn],rmq[maxn << 1];
int flag[maxn];
int vis[maxn],xo[maxn];
int P[maxn],val[maxn];
int F[maxn<<1];
int Size[maxn];
int pos[maxn],sid; struct Edge
{
int to,next;
} edge[maxn << 1]; void add_edge(int u,int v)
{
edge[tot].to = v,edge[tot].next=head[u],head[u] = tot++;
} struct ST
{
int m[maxn << 1];
int dp[maxn << 1][20];
void ini(int n)
{
m[0] = -1;
for(int i = 1; i <= n; i++)
{
m[i] = ((i&(i-1)) == 0)? m[i-1]+1:m[i-1];
dp[i][0] = i;
}
for(int j = 1; j <= m[n]; j++)
{
for(int i = 1; i+(1<<j)-1 <= n; i++)
dp[i][j] = rmq[dp[i][j-1]] < rmq[dp[i+(1<<(j-1))][j-1]] ?
dp[i][j-1] : dp[i+(1 << (j-1))][j-1];
}
}
int query(int a,int b)
{
if(a > b)
swap(a,b);
int k = m[b-a+1];
return rmq[dp[a][k]] <= rmq[dp[b-(1<<k)+1][k]] ?
dp[a][k]:dp[b-(1<<k)+1][k];
}
}; ST st; void dfs(int u,int pre,int dep,int Xor)
{
F[++cnt] = u;
rmq[cnt] = dep;
P[u] = cnt;
Size[u] = 1;
pos[u] = ++sid;
Xor ^= val[u];
xo[sid] = Xor;
for(int i = head[u]; ~i; i = edge[i].next)
{
int v = edge[i].to;
if(v == pre)
continue;
dfs(v,u,dep+1,Xor);
Size[u] += Size[v];
F[++cnt] = u;
rmq[cnt] = dep;
}
} int query_lca(int a,int b)
{
return F[st.query(P[a],P[b])];
}
void ini()
{
memset(flag,0,sizeof(flag));
memset(head,-1,sizeof(head));
tot =0;
cnt = sid = 0;
} struct node
{
int l,r;
int val ;
int mid()
{
return (l+r)>>1;
}
} tree[maxn << 2]; void push_up(int i)
{
//tree[i].lca = query_lca(tree[lson].lca,tree[rson].lca);
// cout << tree[lson].lca << " " <<tree[rson].lca <<endl;
// cout << tree[i].l<< " " << tree[i].r << " " <<tree[i].lca <<endl;
} void build(int i,int l,int r)
{
tree[i].l = l,tree[i].r = r;
tree[i].val = 0;
if(l == r)
{
// cout << tree[i].l<< " " << tree[i].r << " " <<tree[i].lca <<endl;
return ;
}
int mid = tree[i].mid();
build(lson,l,mid);
build(rson,mid+1,r);
push_up(i);
} void push_down(int i)
{
if(tree[i].val)
{
tree[lson].val ^= tree[i].val;
tree[rson].val ^= tree[i].val;
tree[i].val = 0;
}
} void update(int i,int l,int r,int val)
{
if(tree[i].l >= l && r >= tree[i].r )
{
tree[i].val ^= val;
return ;
}
push_down(i);
int mid = tree[i].mid();
if(l <= mid)
update(lson,l,r,val);
if(r > mid)
update(rson,l,r,val);
push_up(i);
} int query(int i,int k)
{
if(tree[i].l == tree[i].r )
{
xo[tree[i].l] ^= tree[i].val;
tree[i].val = 0;
return xo[tree[i].l];
}
int mid = tree[i].mid();
push_down(i);
if(k <= mid)
return query(lson,k);
else
return query(rson,k);
} int main()
{
int n,m,k;
int a,b,c;
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
ini(); for(int i = 1; i < n; i++)
{
scanf("%d%d",&a,&b);
add_edge(a,b);
add_edge(b,a); flag[b] = 1;
}
int root= 1;
for(int i = 1; i <= n; i++)
{
scanf("%d",&val[i]),val[i]++;
if(!flag[i])
root = i;
}
dfs(root,root,0,0);
st.ini(2*n-1);
build(1,1,sid+1);
// cout << sid <<endl;
int op;
// printf("1 2 %d\n",query_lca(1,2));
for(int i = 1; i <= m; i++)
{
scanf("%d",&op);
scanf("%d%d",&a,&b);
if(op == 1)
{
int lca = query_lca(a,b);
int ta = query(1,pos[a]);
int tb = query(1,pos[b]);
if((ta ^ tb ^ val[lca]) == 0)
printf("-1\n");
else
printf("%d\n",(ta ^ tb ^ val[lca])-1);
}
else
{
int from = pos[a];
b ++ ;
update(1,from,from+Size[a]-1,val[a]^b);
val[a] = b;
}
}
}
return 0;
}

  

hdu 5274 Dylans loves tree(LCA + 线段树)的更多相关文章

  1. Hdu 5274 Dylans loves tree &lpar;树链剖分模板&rpar;

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

  2. hdu 5274 Dylans loves tree &lpar;树链剖分 &plus; 线段树 异或)

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

  3. HDU 5274 Dylans loves tree 树链剖分&plus;线段树

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

  4. hdu 5274 Dylans loves tree

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

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

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

  6. HDU 5274 Dylans loves tree(LCA&plus;dfs时间戳&plus;成段更新 OR 树链剖分&plus;单点更新)

    Problem Description Dylans is given a tree with N nodes. All nodes have a value A[i].Nodes on tree i ...

  7. hdu Dylans loves tree &lbrack;LCA&rsqb; &lpar;树链剖分&rpar;

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

  8. HDU 5266 pog loves szh III 线段树,lca

    Pog and Szh are playing games. Firstly Pog draw a tree on the paper. Here we define 1 as the root of ...

  9. HDU 5266 pog loves szh III &lpar;线段树&plus;在线LCA转RMQ&rpar;

    题目地址:HDU 5266 这题用转RMQ求LCA的方法来做的很easy,仅仅须要找到l-r区间内的dfs序最大的和最小的就能够.那么用线段树或者RMQ维护一下区间最值就能够了.然后就是找dfs序最大 ...

随机推荐

  1. Google Maps API V3 之绘图库 信息窗口

    Google官方教程: Google 地图 API V3 使用入门 Google 地图 API V3 针对移动设备进行开发 Google 地图 API V3 之事件 Google 地图 API V3 ...

  2. ngui的tween的tweenFactor属性

    ngui的tween的tweenFactor属性 这个属性是用来记录动画运行的位置的.可以通过设置它来达到动画运行到一半从新设置从新开始

  3. iOS Question

    Q1: dyld: Library not loaded: @rpath/libswiftCore.dylib 1. 退出 Xcode2. 重启电脑3. 找到 这个 DerivedData 文件夹 删 ...

  4. D - Half of and a Half 大数

    D - Half of and a Half Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I ...

  5. struts2重点——ValueStack和OGNL

    一.值栈(ValueStack) 1.实现类:OGNLValueStack 2.对象栈:CompoundRoot(针对的是类级别的) (1)继承自 ArrayList —— 先进后出 (2)提供了栈的 ...

  6. 对memcpy函数的改进

    void *mymemcpy(void *dst,const void *src,size_t num) { assert((dst!=NULL)&&(src!=NULL)); int ...

  7. 二 J2EE 概述

    一 WEB 应用 1. WEB 应用工作方式:B/S 模式 (浏览器/服务器模式) 2. WEB 应用结构组成: a. WEB 服务器:是安装在 WEB 服务器计算机上的一个软件包,负责接收用户请求并 ...

  8. (7)如何得到所有的 &quot&semi;水仙花数&quot&semi; &quest;

    本程序转载自:如何得到所有的水仙花数 感谢Android_iPhone(日知己所无),preferme(冰思雨)等人: package test; import java.math.BigIntege ...

  9. Ubuntu 16&period;04 LTS 正式发布:系统将持续更新5年

    Canonical 刚刚正式发布了Ubuntu 16.04 LTS (Xenial Xerus),这是一个长期支持版本,官方会提供长达5年的技术支持(包括常规更新/Bug修复/安全升级),一直到202 ...

  10. Chapter 1 Securing Your Server and Network&lpar;1&rpar;&colon;选择SQL Server运行账号

    原文:Chapter 1 Securing Your Server and Network(1):选择SQL Server运行账号 原文出处:http://blog.csdn.net/dba_huan ...