HDU 5274 Dylans loves tree(LCA+dfs时间戳+成段更新 OR 树链剖分+单点更新)
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
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).
1
3 2
1 2
2 3
1 1 1
1 1 2
1 1 3
-1
1HintIf 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.
大致题意:
一棵树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 树链剖分+单点更新)的更多相关文章
- hdu 5274 Dylans loves tree(LCA + 线段树)
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- Hdu 5274 Dylans loves tree (树链剖分模板)
Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...
- 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 树链剖分+线段树
Dylans loves tree Problem Description Dylans is given a tree with N nodes. All nodes have a value A[ ...
- HDU 5274 Dylans loves tree(树链剖分)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5274 [题目大意] 给出一棵树,每个点有一个权值,权值可修改,且大于等于0,询问链上出现次数为奇数 ...
- hdu 5274 Dylans loves tree (树链剖分 + 线段树 异或)
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- hdu Dylans loves tree [LCA] (树链剖分)
Dylans loves tree view code#pragma comment(linker, "/STACK:1024000000,1024000000") #includ ...
- BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )
做一次MST, 枚举不在最小生成树上的每一条边(u,v), 然后加上这条边, 删掉(u,v)上的最大边(或严格次大边), 更新答案. 树链剖分然后ST维护最大值和严格次大值..倍增也是可以的... - ...
- AC日记——Dylans loves tree hdu 5274
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
随机推荐
- Java设计模式学习二
Java设计思想之单例模式 单例模式(Singleton Pattern)是Java中最常见的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式涉及到一个单一的 ...
- 爬虫开发python工具包介绍 (3)
本文来自网易云社区 作者:王涛 :arg str url: URL to fetch :arg str method: HTTP method, e.g. " ...
- find_element——By 元素定位
• find_element(By.ID,”loginName”)• find_element(By.NAME,”SubjectName”)• find_element(By.CLASS_NAME,” ...
- 在 Yii2 项目中使用 Composer 添加 FontAwesome 字体资源
2014-06-21 19:05 原文 简体 繁體 2,123 次围观 前天帮同事改个十年前的网站 bug,页面上一堆 include require 不禁让人抱头痛哭.看到 V2EX 上的讨论说,写 ...
- 【编程工具】Sublime Text3 之 Emmet 插件的详细使用的方法
这篇关于 Emmet 插件使用的博文之前就想写了,今天刚好闲暇时间,就花了一些时间进行了总结. 我们都这道 Emmet 这款插件在前端设计里被称为神器,确实,神器称号名不虚传.因为这款插件可以帮助我们 ...
- [uiautomator篇] uiautoviewer 定位不到元素
定位工具: Uiautomatorviewer 在我们的APP中,只有这一个页面,元素无法加载出来,其它的都没有什么问题. 提示的错误:Error while obtaining UI hiera ...
- 【C#】最后总结
导读:要想收获,就逃不开总结.一直拖着拖着,再也无法忍受了.应该说是又学习迷茫了,所以,我要总结.一直都觉得自己总结不出来,或者是看了别人的优秀总结,心里就打鼓,不敢下笔.现在,化用一下:但热闹是他们 ...
- zabbix的安装(一)监控os资源:内存,cpu,io,负载,带宽
一.Linux下开源监控系统简单介绍1)cacti:存储数据能力强,报警性能差2)nagios:报警性能差,存储数据仅有简单的一段可以判断是否在合理范围内的数据长度,储存在内存中.比如,连续采样数据存 ...
- 【Luogu】P1941飞扬的小鸟(DP)
我发现现在没了题解我做普及提高+的题也做不了 更不要说这些提高+难度的题 此题是一个二维DP.暴力是三重循环ijk,k枚举在i位置上的点击次数.即 for(int i=1;i<=n;++i) ...
- BZOJ 4566 [Haoi2016]找相同字符 ——广义后缀自动机
建立广义后缀自动机. 然后统计子树中的siz,需要分开统计 然后对(l[i]-l[fa[i]])*siz[i][0]*siz[i][1]求和即可. #include <cstdio> #i ...