Tree

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)
Total Submission(s): 1643    Accepted Submission(s): 461

Problem Description
  Zero and One are good friends who always have fun with each other. This time, they decide to do something on a tree which is a kind of graph that there is only one path from node to node. First, Zero will give One an tree and every node in this tree has a value. Then, Zero will ask One a series of queries. Each query contains three parameters: x, y, z which mean that he want to know the maximum value produced by z xor each value on the path from node x to node y (include node x, node y). Unfortunately, One has no idea in this question. So he need you to solve it.
 
Input
  There are several test cases and the cases end with EOF. For each case:

The first line contains two integers n(1<=n<=10^5) and m(1<=m<=10^5), which are the amount of tree’s nodes and queries, respectively.

The second line contains n integers a[1..n] and a[i](0<=a[i]<2^{16}) is the value on the ith node.

The next n–1 lines contains two integers u v, which means there is an connection between u and v.

The next m lines contains three integers x y z, which are the parameters of Zero’s query.

 
Output
  For each query, output the answer.

 
Sample Input
3 2
1 2 2
1 2
2 3
 
1 3 1
2 3 2
 
Sample Output
3
0
 

题目链接:HDU 4757

一道跟COT很像的题,但是用的是可持久化的Trie,做法跟COT基本相同,但是过程中由于N少设了10倍,无限TLE……各种纠结问题出在Tarjan?并查集?插入查询函数?因此过程中还找了题解但发现并没有什么区别,但有另外一种非递归形式的插入查询写法,值得借鉴。另外处理节点LCA的问题上公式还是那条$cnt_{U,V}=cnt_{U}+cnt_{V}-cnt_{LCA}-cnt_{father[LCA]}$

单纯地减掉两倍可能会出错,不知道网上的例程是什么情况。通过最近几道题了解了可持久化Trie的空间复杂度似乎跟Trie是一样的,都是Total*maxlen(如果撇开相对来说只有一丢丢的root数组不说的话)

递归更新查询的代码:

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <bitset>
#include <string>
#include <deque>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0);
const int N=1e5+7;
struct Trie
{
int nxt[2];
int cnt;
};
struct edge
{
int to,nxt;
};
struct Query
{
int to,nxt,id,lca;
};
struct ask
{
int u,v,lca,val;
};
ask q[N];
Trie L[N*18];int cnt;
Query Q[N<<1];int qtot,qhead[N];
edge E[N<<1];int tot,head[N];
int ances[N],pre[N],Father[N];
bitset<N>vis;
int arr[N],root[N]; void init()
{
CLR(L,0);cnt=0;
CLR(head,-1);tot=0;
CLR(qhead,-1);qtot=0;
CLR(ances,0);
for (int i=0; i<N; ++i)
pre[i]=i;
CLR(Father,0);
vis.reset();
CLR(root,0);
}
inline void add(const int &s,const int &t)
{
E[tot].to=t;
E[tot].nxt=head[s];
head[s]=tot++;
}
inline void addQ(const int &s,const int &t,const int &id)
{
Q[qtot].to=t;
Q[qtot].id=id;
Q[qtot].lca=1;
Q[qtot].nxt=qhead[s];
qhead[s]=qtot++;
} void update(int &cur,const int &ori,const int &step,const int &n)
{
cur=++cnt;
L[cur]=L[ori];
++L[cur].cnt;
if(step<0)
return;
int t=(n>>step)&1;
update(L[cur].nxt[t],L[ori].nxt[t],step-1,n);
}
int Find(const int &n)
{
return n==pre[n]?n:pre[n]=Find(pre[n]);
}
void Tarjan(const int &u,const int &Fa)
{
vis[u]=1;
ances[u]=u;
Father[u]=Fa;
update(root[u],root[Fa],16,arr[u]);
for (int i=head[u]; ~i; i=E[i].nxt)
{
int v=E[i].to;
if(!vis[v])
{
Tarjan(v,u);
pre[v]=u;
ances[Find(u)]=u;
}
}
for (int i=qhead[u]; ~i; i=Q[i].nxt)
{
int v=Q[i].to;
if(vis[v])
q[Q[i].id].lca=ances[Find(v)];
}
}
int query(const int &U,const int &V,const int &LCA,const int &F_LCA,const int &step,const int &n)
{
if(step<0)
return 0;
int t=(n>>step)&1;
int c=L[L[U].nxt[t^1]].cnt+L[L[V].nxt[t^1]].cnt-L[L[LCA].nxt[t^1]].cnt-L[L[F_LCA].nxt[t^1]].cnt;
if(c>0)
return (1<<step)+query(L[U].nxt[t^1],L[V].nxt[t^1],L[LCA].nxt[t^1],L[F_LCA].nxt[t^1],step-1,n);
else
return query(L[U].nxt[t],L[V].nxt[t],L[LCA].nxt[t],L[F_LCA].nxt[t],step-1,n);
}
int main(void)
{
int n,m,a,b,i;
while (~scanf("%d%d",&n,&m))
{
init();
for (i=1; i<=n; ++i)
scanf("%d",&arr[i]);
for (i=0; i<n-1; ++i)
{
scanf("%d%d",&a,&b);
add(a, b);
add(b, a);
}
for (i=0; i<m; ++i)
{
scanf("%d%d%d",&q[i].u,&q[i].v,&q[i].val);
addQ(q[i].u, q[i].v, i);
addQ(q[i].v, q[i].u, i);
}
Tarjan(1,0);
for (i=0; i<m; ++i)
printf("%d\n",query(root[q[i].u],root[q[i].v],root[q[i].lca],root[Father[q[i].lca]],16,q[i].val));
}
return 0;
}

网上例程的非递归写法:

int update(int ori,int n)
{
bitset<17> s=n;
int cur=++cnt;
int ret=cur;
L[cur]=L[ori];
for (int i=16; i>=0; --i)
{
int v=s[i];
L[++cnt]=L[L[cur].nxt[v]];
++L[cnt].cnt;
L[cur].nxt[v]=cnt;
cur=cnt;
}
return ret;
}
void Tarjan(const int &u,const int &Fa)
{
/*vis[u]=1;
ances[u]=u;
Father[u]=Fa;*/
root[u]=update(root[Fa],arr[u]);
/*for (int i=head[u]; ~i; i=E[i].nxt)
{
int v=E[i].to;
if(!vis[v])
{
Tarjan(v,u);
pre[v]=u;
ances[Find(u)]=u;
}
}
for (int i=qhead[u]; ~i; i=Q[i].nxt)
{
int v=Q[i].to;
if(vis[v])
q[Q[i].id].lca=ances[Find(v)];
}*/
}
int query(int u,int v,int lca,int flca,int n)
{
int r=0;
bitset<17> s=n;
for (int i=16; i>=0; --i)
{
int indx=s[i];
int c=L[L[u].nxt[indx^1]].cnt+L[L[v].nxt[indx^1]].cnt-L[L[lca].nxt[indx^1]].cnt-L[L[flca].nxt[indx^1]].cnt;
if(c>0)
{
r+=1<<i;
u=L[u].nxt[indx^1];
v=L[v].nxt[indx^1];
lca=L[lca].nxt[indx^1];
flca=L[flca].nxt[indx^1];
}
else
{
u=L[u].nxt[indx];
v=L[v].nxt[indx];
lca=L[lca].nxt[indx];
flca=L[flca].nxt[indx];
}
}
return r;
}

HDU 4757 Tree(可持久化Trie+Tarjan离线LCA)的更多相关文章

  1. HDU.4757.Tree(可持久化Trie)

    题目链接 \(Description\) 给定一棵树,点有点权.\(Q\)次询问\(x,y,z\),求\(x\)到\(y\)的简单路径中,与\(z\)异或能得到的最大的数是多少. \(Solution ...

  2. HDU 4757 Tree 可持久化字典树 trie

    http://acm.hdu.edu.cn/showproblem.php?pid=4757 给出一棵树,每个节点有权值,每次查询节点 (u,v) 以及 val,问 u 到 v 路径上的某个节点与 v ...

  3. HDU 4757 Tree 可持久化字典树

    Tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4757 Des ...

  4. HDU 4757 Tree(可持久化trie)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4757 题意:给出一棵树,节点有权值.每次询问x到y的路径上与z抑或的最大值. 思路:可持久化trie. ...

  5. HDU 4757 Tree

    传送门 Tree Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Prob ...

  6. SPOJ 10628 Count on a tree(Tarjan离线LCA+主席树求树上第K小)

    COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to  ...

  7. HDU 4757 Tree(可持久化字典树)(2013 ACM/ICPC Asia Regional Nanjing Online)

    Problem Description   Zero and One are good friends who always have fun with each other. This time, ...

  8. HDU4757 Tree(可持久化Trie)

    写过可持久化线段树,但是从来没写过可持久化的Trie,今天补一补. 题目就是典型的给你一个数x,和一个数集,问x和里面的某个数xor起来的最大值是多少. 最原始的是数集是固定的,只需要对数集按照高到低 ...

  9. HDU 4757 Tree(可持续化字典树,lca)

    题意:询问树上结点x到结点y路上上的权值异或z的最大值. 任意结点权值 ≤ 2^16,可以想到用字典树. 但是因为是询问某条路径上的字典树,将字典树可持续化,字典树上的结点保存在这条路径上的二进制数. ...

随机推荐

  1. 【Alpha】Daily Scrum Meeting第五次

    一.本次Daily Scrum Meeting主要内容 每个人学习情况 任务安排 界面设计问题,怎样让界面更好看? 二.任务安排 学号尾数 昨天做的任务 今天的任务 明天的任务 612 时间轴控件优化 ...

  2. DB2表的重组

    DB2在存储大数据的时候,遇到一个问题,将数据导入表中保存不了,最后是重组后才解决. 下面是从IBM官网上搜集的资料: 官网地址:http://publib.boulder.ibm.com/infoc ...

  3. Python之路,Day2 - Python基础2

    def decode(self, encoding=None, errors=None): """ 解码 """ ""& ...

  4. 5.openstack之mitaka搭建计算节点

    部署计算节点(compute服务) 一:控制节点配置 1.建库建用户 CREATE DATABASE nova_api; CREATE DATABASE nova; GRANT ALL PRIVILE ...

  5. python中如何避免中文是乱码

    这个问题是一个具有很强操作性的问题.我这里有一个经验总结,分享一下,供参考:首先,提倡使用utf-8编码方案,因为它跨平台不错.经验一:在开头声明: # -*- coding: utf-8 -*- 有 ...

  6. 用Myeclipse,包名上有小红叉(表示错误),但是包中的类都是没有错误的+struts2继承ActionSupport时package前面出错

    使用Eclipse 进行项目开发,在实现类中的方法前面如果添加@Override就提示“Multiple markers at this line”的错误,问题描述如下 应该是JDK版本的问题, 右击 ...

  7. canvas画圆百分比显示

    代码如下,由于canvas还是不太熟悉,还有很多欠缺,希望大家多提意见,谢谢 function DrawArc(id,opations){ this.canvas = document.getElem ...

  8. 利用Queue队列实现FIFO的算法

    #!/usr/bin/env python # -*- coding: utf-8 -*- # learn <<Problem Solving with Algorithms and Da ...

  9. python下编译py成pyc和pyo

     python下编译py成pyc和pyo   其实很简单, 用 python -m py_compile file.py python -m py_compile /root/src/{file1,f ...

  10. [转载]config文件的一个很好的实现

    以下是转载于网上的一个很好的config文件的实现,留存以备案 //Config.h #pragma once #include <string> #include <map> ...