【BZOJ 2588】 Spoj 10628. Count on a tree|树上K大|树链剖分|主席树

2024-03-02 21:48

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

我沙茶

我沙茶

我沙茶

傻到去写链剖! 本来求个LCA又好写又快.....

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 100010int team[MAXN],head,tail;
int fa[MAXN],son[MAXN],size[MAXN],loc[MAXN],top[MAXN],depth[MAXN];int tot,g[MAXN*2],nnext[MAXN*2],num[MAXN*2];
void Add(int x,int y)
{tot++;nnext[tot]=g[x];g[x]=tot;num[tot]=y;
}void Lian_Pou()
{team[++tail]=1;depth[1]=1;while(head<tail){int x=team[++head];for(int i=g[x];i;i=nnext[i]){int tmp=num[i];if(depth[tmp]!=0) continue ;fa[tmp]=x;depth[tmp]=depth[x]+1;team[++tail]=tmp;}}for(int i=tail;i>=1;i--){int x=team[i];size[x]=1;for(int j=g[x];j;j=nnext[j]){int tmp=num[j];if(tmp==fa[x]) continue ;size[x] += size[tmp];if(size[tmp]>size[son[x]]) son[x]=tmp;}}loc[1]=1;top[1]=1;for(int i=1;i<=tail;i++){int x=team[i];int cnt=loc[x];if(son[x]!=0){loc[son[x]]=cnt+1;top[son[x]]=top[x];cnt+=size[son[x]];}for(int j=g[x];j;j=nnext[j]){int tmp=num[j];if(tmp==fa[x]||tmp==son[x]) continue ;loc[tmp]=cnt+1;top[tmp]=tmp;cnt+=size[tmp];}}
}
struct INIT
{int num;int loc;int no;
} init[MAXN];
bool cmp(INIT a,INIT b) 
{return a.loc<b.loc;
}
bool cmp1(INIT a,INIT b)
{return a.num<b.num;
}int cnt;
int seg_tot;
struct H
{int L,R;int sum;
}seg[MAXN*20];void Seg_Add(int now,int l,int r,int x,int last)
{if(l==r) {seg[now].sum=seg[last].sum+1;;return ;}int mid=(l+r)/2;if(x<=mid) {seg[now].L=++seg_tot;seg[now].R=seg[last].R;last=seg[last].L;Seg_Add(seg[now].L,l,mid,x,last);}else{seg[now].R=++seg_tot;seg[now].L=seg[last].L;last=seg[last].R;Seg_Add(seg[now].R,mid+1,r,x,last);}seg[now].sum=seg[seg[now].L].sum+seg[seg[now].R].sum;
}
int hash[MAXN];
int root[MAXN];
int LL[MAXN],RR[MAXN],LN,RN;
void Solve(int x,int y)
{LN=0;RN=0;while(top[x]!=top[y]){if(depth[top[x]]<depth[top[y]]) swap(x,y);LL[++LN]=root[loc[top[x]]-1];RR[++RN]=root[loc[x]];x=fa[top[x]];}if(depth[x]<depth[y]) swap(x,y);LL[++LN]=root[loc[y]-1];RR[++RN]=root[loc[x]];
}int Q(int l,int r,int k)
{	if(l==r) return l;int S=0;for(int i=1;i<=LN;i++) {S-=seg[seg[LL[i]].L].sum;S+=seg[seg[RR[i]].L].sum;}int mid=(l+r)/2;if(k<=S){for(int i=1;i<=LN;i++) LL[i]=seg[LL[i]].L;for(int i=1;i<=RN;i++) RR[i]=seg[RR[i]].L;return Q(l,mid,k);}else{for(int i=1;i<=LN;i++) LL[i]=seg[LL[i]].R;for(int i=1;i<=RN;i++) RR[i]=seg[RR[i]].R;k-=S;return Q(mid+1,r,k);}
}int main()
{
//	freopen("a.in","r",stdin);
//	freopen("wa.out","w",stdout);int n,m;cin >> n >> m;for(int i=1;i<=n;i++) scanf("%d",&init[i].num);for(int i=1;i<n;i++){int x,y;scanf("%d %d",&x,&y);Add(x,y);Add(y,x);}Lian_Pou();for(int i=1;i<=n;i++) init[i].loc=loc[i];sort(init+1,init+1+n,cmp1);init[1].no=1;for(int i=2;i<=n;i++)if(init[i].num!=init[i-1].num)init[i].no=init[i-1].no+1;else init[i].no=init[i-1].no;cnt=init[n].no;for(int i=1;i<=n;i++) hash[init[i].no]=init[i].num;sort(init+1,init+n+1,cmp);for(int i=1;i<=n;i++){root[i]=++seg_tot;Seg_Add(root[i],1,cnt,init[i].no,root[i-1]);}int last=0;for(int i=1;i<=m;i++){int u,v,k;scanf("%d %d %d",&u,&v,&k);u^=last;Solve(u,v);last=hash[Q(1,cnt,k)];if(i!=m) printf("%d\n",last);else printf("%d",last);}return 0;
}


这篇关于【BZOJ 2588】 Spoj 10628. Count on a tree|树上K大|树链剖分|主席树的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

SPOJ - QTREE (树链剖分)

基础的树链剖分题目,不过是边权,可以向下映射成点权或者按边剖分。 VIEW CODE #include <iostream>#include<stdio.h>#include<cmath>#include<string.h>#include<algorithm>#include<string>using namespace std;const int mmax=100

hdu 2586 树上点对最近距离 (lca)

,只要知道dis[i][j]=dis[i][root]+dis[j][root]-2*dis[Lca(i,j)][root].   其中root为树的根节点,LCA(i,j)为i,j的最近公共祖先。 所以我们先把所有的询问储存下来,然后离线直接查询。复杂度是o(n+q)的。 VIE #include<cstdio>#include<algorithm>#include<i

玩转Web之easyui(二)-----easy ui 异步加载生成树节点(Tree),点击树生成tab(选项卡)

关于easy ui 异步加载生成树及点击树生成选项卡,这里直接给出代码,重点部分代码中均有注释 前台: $('#tree').tree({ url: '../servlet/School_Tree?id=-1', //向后台传送id,获取根节点lines:true,onBeforeExpand:function(node,param){ $('#tree').tree('options'

【C++PCL】点云处理Kd-tree原理

作者:迅卓科技 简介:本人从事过多项点云项目,并且负责的项目均已得到好评! 公众号:迅卓科技,一个可以让您可以学习点云的好地方 重点:每个模块都有参数如何调试的讲解,即调试某个参数对结果的影响是什么,大家有问题可以评论哈,如果文章有错误的地方,欢迎来指出错误的地方。 目录         1.原理介绍 1.原理介绍         kd-tree是散乱点云的一种储存结构,它是一种

count(distinct ...) over (partition by...) 替换成mysql

你这个是用了 Oracle 的分析函数。 SQL Server 是不支持的。如果语句比较简单的。例如SELECT COUNT( distinct A) OVER ( partition by B) FROM C可以修改为:SELECT COUNT( distinct A) FROM CGROUP BY B但是如果你的逻辑很复杂的话,那就麻烦了。

Spark算子:RDDAction操作–first/count/reduce/collect/collectAsMap

first def first(): T first返回RDD中的第一个元素,不排序。 scala> var rdd1 = sc.makeRDD(Array(("A","1"),("B","2"),("C","3")),2)rdd1: org.apache.spark.rdd.RDD[(String, String)] = ParallelCollectionRDD[33] at mak

【SQL】count(1)、count(*) 与 count(列名) 的区别

在 SQL 中,COUNT 函数用于计算查询结果集中的行数。COUNT(1)、COUNT(*) 和 COUNT(列名) 都可以用来统计行数,但它们在实现细节和使用场景上有一些区别。以下是详细的解释: 1. COUNT(1) 定义: COUNT(1) 计算查询结果集中的行数。实现: 在执行过程中,COUNT(1) 会将 1 作为一个非空的常量值,并对每一行进行计数。效率: 现代的 SQL 优化器

[leetcode] 107. Binary Tree Level Order Traversal II

Binary Tree Level Order Traversal II 描述 Given a binary tree, return the bottom-up level order traversal of its nodes’ values. (ie, from left to right, level by level from leaf to root). For example

[leetcode] 102. Binary Tree Level Order Traversal

Binary Tree Level Order Traversal 描述 Given a binary tree, return the level order traversal of its nodes’ values. (ie, from left to right, level by level). For example: Given binary tree [3,9,20

[leetcode] 515. Find Largest Value in Each Tree Row

Find Largest Value in Each Tree Row 描述 You need to find the largest value in each row of a binary tree. Example: Input: 1/ \3 2/ \ \ 5 3 9 Output: [1, 3, 9] 我的代码 简单的dfs。 要使