【树上主席树】BZOJ2588-Count on a tree

时间:2022-09-19 22:44:15

【题目大意】

给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。
 
【思路】
这道题迷之好写,因为思路条理太清晰了!
我们每个点就是一棵线段树,维护它到根的每个数字的个数,但是这样会MLE所以自然而然地用主席树来维护。
u->v路径上每种的个数就等于sum[u]-sum[lca(u,v)]+sum[v]-sum[fa[lca(u,v)]]。
写起来特别爽。
然而我RE了一个上午。接着突然发现题意“(u,v)表示u到v有一条边)它居然是无向的??天真地以为有向u->v,调出了一开始的程序,默默地改掉,默默地AC...
还我两小时的人生!!!!
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define lson l,m
#define rson m+1,r
using namespace std;
const int MAXN=+;
const int DEG=;
int w[MAXN];
vector<int> E[MAXN];
int d,hash[MAXN];
int T[MAXN],tot,sum[MAXN<<],L[MAXN<<],R[MAXN<<];
int anc[MAXN][DEG],dep[MAXN];
int n,m; /*Chairman Tree*/
int build(int l,int r)
{
int rt=++tot;
sum[rt]=;
if (l!=r)
{
int m=(l+r)>>;
L[rt]=build(lson);
R[rt]=build(rson);
}
return rt;
} int update(int pre,int l,int r,int x)
{
int rt=++tot;
L[rt]=L[pre],R[rt]=R[pre];
sum[rt]=sum[pre]+;
if (l!=r)
{
int m=(l+r)>>;
if (x<=m) L[rt]=update(L[pre],lson,x);
else R[rt]=update(R[pre],rson,x);
}
return rt;
} int query(int u,int v,int lca,int lcafa,int l,int r,int k)
{
if (l==r) return l;
int num=(sum[L[u]]-sum[L[lca]]+sum[L[v]]-sum[L[lcafa]]);
int m=(l+r)>>;
if (num>=k) return query(L[u],L[v],L[lca],L[lcafa],lson,k);
else return query(R[u],R[v],R[lca],R[lcafa],rson,k-num);
} /*LCA*/
void getanc()
{
for (int i=;i<DEG;i++)
for (int j=;j<=n;j++)
anc[j][i]=anc[anc[j][i-]][i-];
} int swim(int x,int H)
{
for (int i=;H>;i++)
{
if (H&) x=anc[x][i];
H>>=;
}
return x;
} int LCA(int u,int v)
{
if (dep[u]<dep[v]) swap(u,v);
u=swim(u,dep[u]-dep[v]);
if (u==v) return u;
for (int i=DEG-;i>=;i--)
{
if (anc[u][i]!=anc[v][i])
{
u=anc[u][i];
v=anc[v][i];
}
}
return anc[u][];
} /*main*/
void dfs(int u,int pa,int depth)
{
anc[u][]=pa;
dep[u]=depth;
int x=lower_bound(hash+,hash+d+,w[u])-hash;
T[u]=update(T[pa],,d,x);
for (int i=;i<E[u].size();i++)
if (E[u][i]!=pa) dfs(E[u][i],u,depth+);
} void init()
{
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&w[i]),hash[i]=w[i];
sort(hash+,hash+n+);
d=unique(hash+,hash+n+)-(hash+); for (int i=;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
E[u].push_back(v);
E[v].push_back(u);
} tot=;
T[]=build(,d);//对于根先建立主席树
} void solve()
{
getanc();
int preans=;
for (int i=;i<m;i++)
{
int u,v,k;
scanf("%d%d%d",&u,&v,&k);
u=u^preans;
int lca=LCA(u,v);
int ans=query(T[u],T[v],T[lca],T[anc[lca][]],,d,k);
printf("%d",hash[ans]);
if (i!=m-) printf("\n");
preans=hash[ans];
}
} int main()
{
init();
dfs(,,);
solve();
return ;
}

【树上主席树】BZOJ2588-Count on a tree的更多相关文章

  1. 洛谷P2633&sol;bzoj2588 Count on a tree &lpar;主席树&rpar;

    洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...

  2. Count on a tree 树上主席树

    Count on a tree 树上主席树 给\(n\)个树,每个点有点权,每次询问\(u,v\)路径上第\(k\)小点权,强制在线 求解区间静态第\(k\)小即用主席树. 树上主席树类似于区间上主席 ...

  3. 【洛谷2633】Count on a tree(树上主席树)

    点此看题面 大致题意: 给你一棵树,每次问你两点之间第\(k\)小的点权,强制在线. 主席树 这种题目强制在线一般就是数据结构了. 而看到区间第\(k\)小,很容易就能想到主席树. 至少不会有人想到树 ...

  4. &lbrack;bzoj2588&rsqb;&lbrack;count on a tree&rsqb; &lpar;主席树&plus;lca&rpar;

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

  5. SPOJ COT Count on a tree(树上主席树 &plus; LCA 求点第k小)题解

    题意:n个点的树,每个点有权值,问你u~v路径第k小的点的权值是? 思路: 树上主席树就是每个点建一棵权值线段树,具体看JQ博客,LCA用倍增logn求出,具体原理看这里 树上主席树我每个点的存的是点 ...

  6. p3302 &lbrack;SDOI2013&rsqb;森林(树上主席树&plus;启发式合并)

    对着题目yy了一天加上看了一中午题解,终于搞明白了我太弱了 连边就是合并线段树,把小的集合合并到大的上,可以保证规模至少增加一半,复杂度可以是\(O(logn)\) 合并的时候暴力dfs修改倍增数组和 ...

  7. &lbrack;CSP-S模拟测试&rsqb;&colon;e(树上主席树)

    题目传送门(内部题66) 输入格式 第一行,一个正整数$n$,一个自然数$q$,一个整数$type$.第二行,$n$个正整数,代表$a_i$.接下来$n-1$行,每行两个正整数$u$.$v$,代表树中 ...

  8. bzoj3123 &lbrack;Sdoi2013&rsqb;森林 树上主席树&plus;启发式合并

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3123 题解 如果是静态的查询操作,那么就是直接树上主席树的板子. 但是我们现在有了一个连接两棵 ...

  9. BZOJ2588 Count on a tree 【树上主席树】

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MB Submit: 7577  Solved: 185 ...

随机推荐

  1. 在powerdesigner中创建物理数据模型

    物理数据模型(PDM)是以常用的DBMS(数据库管理系统)理论为基础,将CDM/LDM中所建立的现实世界模型生成相应的DBMS的SQL语言脚本.PDM叙述数据库的物理实现,是对真实数据库的描述 PDM ...

  2. javascript type操作

    var a; type a;//结果为undefined type b;//结果也是undefinedalert(a);//弹出undefinedalert(b);//错误代码  上述代码,type ...

  3. mysql A表部分记录复制到B表

    [不定时更新] 1.将一张表中部分记录的一或多个字段复制到另一张表中: 表A: 表B: 执行SQL: insert into B(f_userId,f_nickname) select f_telep ...

  4. 《Linux内核设计与实现》内存管理札记

    1.页 芯作为物理页存储器管理的基本单元,MMU(内存管理单元)中的页表,从虚拟内存的角度来看,页就是最小单位. 内核用struct page结构来标识系统中的每个物理页.它的定义例如以下: flag ...

  5. 搜索引擎之全文搜索算法功能实现(基于Lucene)

    之前做去转盘网的时候,我已经公开了非全文搜索的代码,需要的朋友希望能够前去阅读我的博客.本文主要讨论如何进行全文搜索,由于本人花了很长时间设计了新作:观点,观点对全文搜索的要求还是很高的,所以我又花了 ...

  6. Kafka的特点及使用场景

    Kafka是分布式发布-订阅消息系统.它最初由LinkedIn公司开发,之后成为Apache项目的一部分.Kafka是一个分布式的,可划分的,冗余备份的持久性的日志服务.它主要用于处理活跃的流式数据. ...

  7. POI读写大数据量excel,解决超过几万行而导致内存溢出的问题

    1. Excel2003与Excel2007 两个版本的最大行数和列数不同,2003版最大行数是65536行,最大列数是256列,2007版及以后的版本最大行数是1048576行,最大列数是16384 ...

  8. CSS初识盒子

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  9. Kubernetes中的nodePort,targetPort,port的区别和意义&lpar;转&rpar;

    原文https://blog.csdn.net/u013760355/article/details/70162242 https://blog.csdn.net/xinghun_4/article/ ...

  10. 再谈数据库优化(database tuning)的真谛和误区

    当今各行业信息量呈现爆炸式增长,因此,数据库优化也就显得弥足重要.随着数据库性能问题的出现,每位用户为了解决出现的问题,不得不满网上到处搜索优化的”灵丹妙药“和捷径,于是,就出现了各种各样的条条框框和 ...