bzoj  2588: Spoj 10628. Count on a tree

http://www.lydsy.com/JudgeOnline/problem.php?id=2588

Description

给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。

Input

第一行两个整数N,M。
第二行有N个整数,其中第i个整数表示点i的权值。
后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
最后M行每行两个整数(u,v,k),表示一组询问。

Output

M行,表示每个询问的答案。最后一个询问不输出换行符

Sample Input

8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2

Sample Output

2
8
9
105
7

HINT

HINT:
N,M<=100000
暴力自重。。。

Source

鸣谢seter

数据结构:主席树

辅助算法:LCA

以点的dfs序为下标,以点权为区间建立主席树

以前做过的主席树在序列上,所以是以前一个节点的线段树为基准建立的

这里在树上,所以可以考虑以根为基准建立线段树

u,v间增加的点数=cnt[u]+cnt[v]-cnt[LCA(u,v)]-cnt[father[LCA(u,v)]]

#include<cstdio>
#include<algorithm>
#define N 100001
using namespace std;
struct count
{
private:
struct node{int l,r,cnt;}tr[N*];
struct data {int to,next;}e[N*];
int n,m,a[N],head[N],edge_cnt;
int dep[N],son[N],f[N],bl[N],sz;
int root[N],cntt,hash[N],hash_tot;
int last;
public:
inline int read()
{
int x=,f=;char c=getchar();
while(c<''||c>'') {if(c=='-') f=-;c=getchar();}
while(c>=''&&c<='') {x=x*+c-'';c=getchar();}
return x*f;
}
inline void add(int u,int v)
{
e[++edge_cnt].to=v;e[edge_cnt].next=head[u];head[u]=edge_cnt;
e[++edge_cnt].to=u;e[edge_cnt].next=head[v];head[v]=edge_cnt;
}
void init()
{
n=read();m=read();
for(int i=;i<=n;i++) a[i]=read(),hash[i]=a[i];
int u,v;
for(int i=;i<n;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
}
}
inline void tree_insert(int pre,int & now,int l,int r,int k)
{
tr[now=++cntt].cnt=tr[pre].cnt+;
if(l==r) return;
int mid=l+r>>;
if(k<=mid)
{
tr[now].r=tr[pre].r;
tree_insert(tr[pre].l,tr[now].l,l,mid,k);
}
else
{
tr[now].l=tr[pre].l;
tree_insert(tr[pre].r,tr[now].r,mid+,r,k);
}
}
inline void dfs1(int x,int fa)
{
son[x]++;
tree_insert(root[fa],root[x],,hash_tot,hash[x]);
for(int i=head[x];i;i=e[i].next)
{
if(e[i].to==fa) continue;
f[e[i].to]=x;
dep[e[i].to]=dep[x]+;
dfs1(e[i].to,x);
son[x]+=son[e[i].to];
}
}
inline void dfs2(int x,int chain)//给重链编号
{
bl[x]=chain;
int m=;
for(int i=head[x];i;i=e[i].next)
{
if(e[i].to==f[x]) continue;
if(son[e[i].to]>son[m]) m=e[i].to;
}
if(!m) return;
dfs2(m,chain);
for(int i=head[x];i;i=e[i].next)
{
if(e[i].to==f[x]||e[i].to==m) continue;
dfs2(e[i].to,e[i].to);
}
}
inline int getlca(int u,int v)//求lca,本函数+上面2个函数为树链剖分求LCA
{
while(bl[u]!=bl[v])
{
if(dep[bl[u]]<dep[bl[v]]) swap(u,v);
u=f[bl[u]];
}
if(dep[u]<dep[v]) return u;
return v;
}
void discrete()
{
sort(a+,a+n+);
hash_tot=unique(a+,a+n+)-(a+);
for(int i=;i<=n;i++) hash[i]=lower_bound(a+,a+hash_tot+,hash[i])-a;
}
inline int tree_query(int x,int y,int lca,int fa_lca,int l,int r,int k)
{
if(l==r) return a[l];
int mid=l+r>>,tmp=tr[tr[x].l].cnt+tr[tr[y].l].cnt-tr[tr[lca].l].cnt-tr[tr[fa_lca].l].cnt;
if(k<=tmp) tree_query(tr[x].l,tr[y].l,tr[lca].l,tr[fa_lca].l,l,mid,k);
else tree_query(tr[x].r,tr[y].r,tr[lca].r,tr[fa_lca].r,mid+,r,k-tmp);
}
void init2()
{
int u,v,k;
for(int i=;i<=m;i++)
{
u=read();v=read();k=read();
u^=last;
int lca=getlca(u,v);
last=tree_query(root[u],root[v],root[lca],root[f[lca]],,hash_tot,k);
if(i!=m )printf("%d\n",last);
else printf("%d",last);
}
}
void work()
{
init();
discrete();
dfs1(,);
dfs2(,);
init2();
} }a;
int main()
{
a.work();
}

初做犯了一个很蠢的错误:最后一行不输出换行,楞是没看见

不读完题,第二次了。

Count on a tree的更多相关文章

  1. BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 5217  Solved: 1233 ...

  2. 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  ...

  3. 【BZOJ-2588】Count on a tree 主席树 + 倍增

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 3749  Solved: 873[ ...

  4. 【BZOJ】【2588】COT(Count On a Tree)

    可持久化线段树 maya……树么……转化成序列……所以就写了个树链剖分……然后每个点保存的是从它到根的可持久化线段树. 然后就像序列一样查询……注意是多个左端点和多个右端点,处理方法类似BZOJ 19 ...

  5. BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树

    2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...

  6. spoj cot: Count on a tree 主席树

    10628. Count on a tree Problem code: COT You are given a tree with N nodes.The tree nodes are number ...

  7. Bzoj 2588: Spoj 10628. Count on a tree 主席树,离散化,可持久,倍增LCA

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588 2588: Spoj 10628. Count on a tree Time Limit ...

  8. BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )

    Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...

  9. SPOJ Count on a tree

    Count on a tree Time Limit:129MS     Memory Limit:1572864KB     64bit IO Format:%lld & %llu Subm ...

  10. 【BZOJ2588】Count On a Tree(主席树)

    [BZOJ2588]Count On a Tree(主席树) 题面 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第 ...

随机推荐

  1. 【BZOJ3529】数表(莫比乌斯反演,树状数组)

    [BZOJ3529]数表(莫比乌斯反演,树状数组) 题解 首先不管\(A\)的范围的限制 要求的东西是 \[\sum_{i=1}^n\sum_{j=1}^m\sigma(gcd(i,j))\] 其中\ ...

  2. 【NOIP2016】蚯蚓(队列,单调性)

    题目不再重复叙述 请参考: 洛谷 CJOJ 题解 先来说说非完美解法,也是我去年考场上的做法 考虑一下每一只蚯蚓增加的长度, 这个值并不需要每一次依次增加, 用一个变量维护即可,每次取出蚯蚓就加上这个 ...

  3. 【NOIP2006】能量项链

    题面 Description 在 Mars 星球上,每个 Mars 人都随身佩带着一串能量项链.在项链上有 N 颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的 ...

  4. 清橙A1212:剪枝

    题面 清橙 Sol 一种新的树上\(DP\)姿势 从左往右按链\(DP\) 做法: 维护两个栈\(S1\),\(S2\) \(S1\)存当前的链 \(S2\)存分叉点以下要改的链 \(Dfs\),弄一 ...

  5. MyBatis笔试题

    1请写出Mybatis核心配置文件MyBatis-config.xml的内容? <?xml version="1.0" encoding="UTF-8"? ...

  6. openflow 和 sdn (软件定义网络) 原理和教程

    OpenFlow概述 OpenFlow简介 通俗的讲,OpenFlow是使用类似于API进程配置网络交换机的协议.OpenFlow的思路很简单,网络设备维护一个FlowTable并且只按照FlowTa ...

  7. 小程序首页onLoad为异步,调用app.js中的全局参数的解决方案。

    一,先说一下遇到的问题: 在首页,为了携带app.js中一些参数去做请求动作,但是由于异步原因,发现请求时候,参数信息还未获取到但请求已经发出去. 若等app.js的全局参数返回来,再携带着它去做请求 ...

  8. webpack学习(七)打包压缩图片

    使用插件webpack-spritesmith生成雪碧图 1.安装webpack-spritesmith:npm install --save-dev webpack-spritesmith 2.配置 ...

  9. 微软Skype Linux客户端全新发布

    前两天,微软说要给“Linux 用户带来一个令人兴奋的新闻”,今天,这个新闻来了.它刚刚为 Linux 发布了一个新的 Skype 客户端. 此次发布,微软为 Linux 带来的 Skype 客户端与 ...

  10. java 三种工厂模式

    一.简单工厂模式 一个栗子: 我喜欢吃面条,抽象一个面条基类,(接口也可以),这是产品的抽象类. public abstract class INoodles { /** * 描述每种面条啥样的 */ ...