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 (树链剖分模板)

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

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

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

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

    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+dfs时间戳+成段更新 OR 树链剖分+单点更新)

    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 [LCA] (树链剖分)

    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 (线段树+在线LCA转RMQ)

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

随机推荐

  1. Welcome to Django!

    Welcome to Django! 实验简介 Django是一个可以使Web开发工作更加高效愉快的Web开发框架.Django可以让你用最小的代价构建和维护更高质量的Web应用程序. 从好的方面来看 ...

  2. android使用sharesdk的小感

    1.sharesdk快捷方式,快捷方式集成了所有需要分享到的手机app,但是具有缺陷,举个例子(想要微信分享图片url,但是短信并不想带有图片,否则短信成彩信,这里集成的就有麻烦了,为了解决这种问题, ...

  3. 在ArcGIS中导出现有mxd的style文件

     做好的地图包含许多地图符号,这是之前花了很多功夫做的,怎么把它导出来再用呢?     在ArcGIS中右键工具栏,customize,选择command选项卡,在搜索框中输入style ,选择too ...

  4. Android类加载机制及热修复实现

    Android类加载机制 Dalvik虚拟机如同其他Java虚拟机一样,在运行程序时首先需要将对应的类加载到内存中.而在Java标准的虚拟机中,类加载可以从class文件中读取,也可以是其他形式的二进 ...

  5. hadoop2.6.0实践:000 虚拟机配置

  6. Jmeter入门(01)Jmeter的下载和安装

    一.什么是Jmeter 1.一款优秀的.开源的.免费的.功能测试和性能测试 工具 Jmeter ,使用Java开发的一款优秀的开源免费测试工具,主要用来做功能测试和性能测试(压力测试/负载测试),用J ...

  7. Spring MVC拦截器的配置

    最近在用SpringMVC,想用它的拦截器,但是配置了几次都不成功了,最后翻阅了不少文章终于成功了,遂记录于此,以方便他人. 首先引入命名空间: xmlns:mvc="http://www. ...

  8. ssm框架找不到mysql驱动类WARN DriverManagerDataSource:107 - Could not load driverClass com.mysql.jdbc.Driver

    找了很久错误,检查了配置文件,和spring配置数据源,都没有发现问题,最后上网查询了下,发现是由于配置文件后面有空格. 去除掉配置文件后面的空格就可以正常运行了.

  9. Java并发编程:synchronized和锁优化

    1. 使用方法 synchronized 是 java 中最常用的保证线程安全的方式,synchronized 的作用主要有三方面: 确保线程互斥的访问代码块,同一时刻只有一个方法可以进入到临界区 保 ...

  10. 解决cors跨域的filter

    import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.Ordered; im ...