hdu 5274 Dylans loves tree(LCA + 线段树)
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
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
(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).
/*
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 + 线段树)的更多相关文章
- Hdu 5274 Dylans loves tree (树链剖分模板)
Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...
- hdu 5274 Dylans loves tree (树链剖分 + 线段树 异或)
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- HDU 5274 Dylans loves tree 树链剖分+线段树
Dylans loves tree Problem Description Dylans is given a tree with N nodes. All nodes have a value A[ ...
- hdu 5274 Dylans loves tree
Dylans loves tree http://acm.hdu.edu.cn/showproblem.php?pid=5274 Time Limit: 2000/1000 MS (Java/Othe ...
- HDU 5274 Dylans loves tree(树链剖分)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5274 [题目大意] 给出一棵树,每个点有一个权值,权值可修改,且大于等于0,询问链上出现次数为奇数 ...
- HDU 5274 Dylans loves tree(LCA+dfs时间戳+成段更新 OR 树链剖分+单点更新)
Problem Description Dylans is given a tree with N nodes. All nodes have a value A[i].Nodes on tree i ...
- hdu Dylans loves tree [LCA] (树链剖分)
Dylans loves tree view code#pragma comment(linker, "/STACK:1024000000,1024000000") #includ ...
- 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 ...
- HDU 5266 pog loves szh III (线段树+在线LCA转RMQ)
题目地址:HDU 5266 这题用转RMQ求LCA的方法来做的很easy,仅仅须要找到l-r区间内的dfs序最大的和最小的就能够.那么用线段树或者RMQ维护一下区间最值就能够了.然后就是找dfs序最大 ...
随机推荐
- Vue.js学习
<!DOCTYPE html> <html> <head> <title>xxx</title> </head> <bod ...
- 201621123068 Week04-面向对象设计与继承
1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 答:继承.多态.重载.关键字.父类与子类 1.2 尝试使用思维导图将这些关键词组织起来. 2. 书面作业 1. 面向对象设计(大 ...
- python3变量和数据类型
变量和数据类型 知识点 python 关键字 变量的定义与赋值 input() 函数 字符串的格式化 实验步骤 每一种编程语言都有它们自己的语法规则,就像我们所说的外语. 1. 关键字和标识符 ...
- 网上找的hadoop面试题目及答案
1.Hadoop集群可以运行的3个模式? 单机(本地)模式 伪分布式模式全分布式模式2. 单机(本地)模式中的注意点? 在单机模式(standalone)中不会存在守护进程,所有东西都运行在一个JVM ...
- Java中RuntimeException和Exception的区别
[TOC] 1. 引入RuntimeException public class RuntimeException { public static void main(String[] args) { ...
- python之路--day13-模块
1,什么是模块 模块就是系统功能的集合体,在python中,一个py文件就是一个模块, 例如:module.py 其中module叫做模块名 2,使用模块 2.1 import导入模块 首次带入模块发 ...
- JAVA中的Log4j
Log4j的简介: 使用异常处理机制==>异常 使用debug调试(必须掌握) System.out.Print(); 001.控制台行数有限制 002.影响性能 ...
- Tomcat(1-1)重置Tomcat8.5管理员的用户名和密码
1.访问 http://localhost:8080/,点击 [manager app],提示输入用户名和密码,admin/admin后报错. 2.解决办法:重置Tomcat8.5管理员的用户名和密 ...
- Let's Encrypt,免费好用的 HTTPS 证书
很早之前我就在关注 Let's Encrypt 这个免费.自动化.开放的证书签发服务.它由 ISRG(Internet Security Research Group,互联网安全研究小组)提供服务,而 ...
- SVN (TortioseSVN) 版本控制之忽略路径(如bin、obj、gen)
在SVN版本控制时,新手经常会遇到这样的问题: 1.整个项目一起提交时会把bin . gen . .project 一同提交至服务器 2.避免提交编译.本地配置等文件在项目中单独对src.res进行提 ...