Bzoj 2588 Spoj 10628. Count on a tree(树链剖分LCA+主席树)

2023-12-25 15:58

本文主要是介绍Bzoj 2588 Spoj 10628. Count on a tree(树链剖分LCA+主席树),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2588: Spoj 10628. Count on a tree
Time Limit: 12 Sec Memory Limit: 128 MB
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:
N,M<=100000
暴力自重。。。
Source
鸣谢seter

/*
树上第K大.
对于每一个节点
以key为下标
用一颗权值线段树维护它到根的路径的区间K大值.
然后用主席树维护.
树剖求lca.
ans=tree[x].size+tree[y].size-tree[lca].size-tree[lca_father].size.
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#define MAXN 100001
using namespace std;
int n,m,ans,cut,maxsize,root[MAXN],tot,s[MAXN],a[MAXN],head[MAXN];
int fa[MAXN],pos[MAXN],top[MAXN],deep[MAXN],size[MAXN];
struct data{int lc,rc,size;}tree[MAXN*20];
struct node{int v,next;}e[MAXN*2];
int read()
{int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();return x*f;
}
void add(int u,int v)
{e[++cut].v=v;e[cut].next=head[u];head[u]=cut;
}
void add(int &k,int last,int l,int r,int x)
{k=++tot;tree[k].lc=tree[last].lc,tree[k].rc=tree[last].rc;tree[k].size=tree[last].size+1;if(l==r) return ;int mid=(l+r)>>1;if(x<=mid) add(tree[k].lc,tree[last].lc,l,mid,x);else add(tree[k].rc,tree[last].rc,mid+1,r,x);return ;
}
void dfs1(int u,int f)
{size[u]=1;int p=lower_bound(s+1,s+n+1,a[u])-s;add(root[u],root[f],1,n,p);for(int i=head[u];i;i=e[i].next){int v=e[i].v;if(v!=f) fa[v]=u,deep[v]=deep[u]+1,dfs1(v,u),size[u]+=size[v];}return ;
}
void dfs2(int u,int top1)
{int k=0;pos[u]=++maxsize;top[u]=top1;for(int i=head[u];i;i=e[i].next){int v=e[i].v;if(fa[v]==u&&size[v]>size[k]) k=v;}if(!k) return ;dfs2(k,top1);for(int i=head[u];i;i=e[i].next){int v=e[i].v;if(fa[v]==u&&v!=k) dfs2(v,v);}return ;
}
int lca(int x,int y)
{fa[1]=1;while(top[x]!=top[y]){if(deep[top[x]]<deep[top[y]]) swap(x,y);//1 R.x=fa[top[x]];}fa[1]=0;if(pos[x]>pos[y]) swap(x,y);return x;
}
int query(int L,int R,int lc,int falc,int l,int r,int k)
{if(l==r) return l;int mid=(l+r)>>1;int sum=tree[tree[L].lc].size+tree[tree[R].lc].size-tree[tree[lc].lc].size-tree[tree[falc].lc].size;if(sum>=k)return query(tree[L].lc,tree[R].lc,tree[lc].lc,tree[falc].lc,l,mid,k);else return query(tree[L].rc,tree[R].rc,tree[lc].rc,tree[falc].rc,mid+1,r,k-sum);
}
void slovequery(int x,int y,int k)
{int lc=lca(x,y);ans=query(root[x],root[y],root[lc],root[fa[lc]],1,n,k);printf("%d",ans=s[ans]);return ;
}
int main()
{int x,y,z;n=read(),m=read();for(int i=1;i<=n;i++) s[i]=a[i]=read();for(int i=1;i<=n-1;i++) x=read(),y=read(),add(x,y),add(y,x);sort(s+1,s+n+1);dfs1(1,0),dfs2(1,1),fa[1]=0;while(m!=1){x=read(),y=read(),z=read();x^=ans;slovequery(x,y,z);m--;printf("\n");//2 W.}x=read(),y=read(),z=read();x^=ans;slovequery(x,y,z);return 0;
}

这篇关于Bzoj 2588 Spoj 10628. Count on a tree(树链剖分LCA+主席树)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/536069

相关文章

poj1330(LCA最近公共祖先)

题意:求最近公共祖先 思路:之前学习了树链剖分,然后我就用树链剖分的一小部分知识就可以解这个题目了,记录每个结点的fa和depth。然后查找时,每次将depth大的结点往上走直到x = y。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring>

树(Tree)——《啊哈!算法》

树 什么是树?树是一种特殊的图,不包含回路的连通无向树。 正因为树有着“不包含回路”这个特点,所以树就被赋予了很多特性。 一棵树中的任意两个结点有且仅有唯一的一条路径连通。一棵树如果有n个结点,那么它一定恰好有n-1条边。在一棵树中加一条边将会构成一个回路。 一棵树有且只有一个根结点。 没有父结点的结点称为根结点(祖先)。没有子结点的结点称为叶结点。如果一个结点既不是根结点也不是叶

226 Invert Binary Tree

//226 Invert Binary Tree//算法思路:主要使用递归算法public class Solution {public TreeNode invertTree(TreeNode root) {//1 出口 空节点if (root==null)return null;//2 递归 调用自己TreeNode left = root.left;TreeNode right = ro

leetcode#38. Count and Say

The count-and-say sequence is the sequence of integers with the first five terms as following: 1. 12. 113. 214. 12115. 111221 1 is read off as “one 1” or 11. 11 is read off

Sorry!Hbase的LSM Tree就是可以为所欲为!

我们先抛出一个问题: LSM树是HBase里使用的非常有创意的一种数据结构。在有代表性的关系型数据库如MySQL、SQL Server、Oracle中,数据存储与索引的基本结构就是我们耳熟能详的B树和B+树。而在一些主流的NoSQL数据库如HBase、Cassandra、LevelDB、RocksDB中,则是使用日志结构合并树(Log-structured Merge Tree,LSM Tr

【spring】does not have member field ‘com.sun.tools.javac.tree.JCTree qualid

spring-in-action-6-samples 的JDK版本 最小是11,我使用 了22: jdk21 jdk22 都与lombok 不兼容,必须使用兼容版本, 否则报错: thingsboard 的大神解释了: java: java.lang.NoSuchFieldError: Class com

[LeetCode] 863. All Nodes Distance K in Binary Tree

题:https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/ 题目大意 求给树中,距给定 结点 指定长度的 所有结点的val 思路 tree -> graph 、 bfs 先遍历树,并用map记录每个结点的父结点 ,将树变为图,然后 bfs。 /*** Definition for a binary tree

《Learning To Count Everything》CVPR2021

摘要 论文提出了一种新的方法来解决视觉计数问题,即在给定类别中仅有少量标注实例的情况下,对任何类别的对象进行计数。将计数问题视为一个少样本回归任务,并提出了一种新颖的方法,该方法通过查询图像和查询图像中的少量示例对象来预测图像中所有感兴趣对象的存在密度图。此外,还提出了一种新颖的适应策略,使网络能够在测试时仅使用新类别中的少量示例对象来适应任何新的视觉类别。为了支持这一任务,作者还引入了一个包含

class _ContiguousArrayStorage deallocated with non-zero retain count

Xcode报错 : Object 0x11c614000 of class _ContiguousArrayStorage deallocated with non-zero retain count 2. This object's deinit, or something called from it, may have created a strong reference to self w

js实现树级递归,通过js生成tree树形菜单(递归算法)

1、效果图 需求:首先这是一个数据集—js的类型,我们需要把生成一个tree形式的对象 : var data = [{ id: 1, name: "办公管理", pid: 0 },{ id: 2, name: "请假申请", pid: 1 },{ id: 3, name: "出差申请", pid: 1 },{ id: 4, name: "请假记录", pid: 2 },{ id: