Count on a tree
bzoj 2588: Spoj 10628. Count on a tree
http://www.lydsy.com/JudgeOnline/problem.php?id=2588
Description
Input
Output
M行,表示每个询问的答案。最后一个询问不输出换行符
Sample Input
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
8
9
105
7
HINT
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*20];struct data {int to,next;}e[N*2];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=0,f=1;char c=getchar();while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';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=1;i<=n;i++) a[i]=read(),hash[i]=a[i];int u,v;for(int i=1;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+1;if(l==r) return;int mid=l+r>>1;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+1,r,k); }}inline void dfs1(int x,int fa) {son[x]++;tree_insert(root[fa],root[x],1,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]+1;dfs1(e[i].to,x);son[x]+=son[e[i].to];}}inline void dfs2(int x,int chain)//给重链编号 {bl[x]=chain;int m=0;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+1,a+n+1);hash_tot=unique(a+1,a+n+1)-(a+1);for(int i=1;i<=n;i++) hash[i]=lower_bound(a+1,a+hash_tot+1,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>>1,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+1,r,k-tmp);}void init2(){int u,v,k;for(int i=1;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]],1,hash_tot,k);if(i!=m )printf("%d\n",last);else printf("%d",last);}}void work(){init();discrete();dfs1(1,0);dfs2(1,1);init2();}}a; int main() {a.work(); }
初做犯了一个很蠢的错误:最后一行不输出换行,楞是没看见
不读完题,第二次了。
转载于:https://www.cnblogs.com/TheRoadToTheGold/p/6383854.html
Count on a tree相关推荐
- bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)
Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MB Submit: 7669 Solved: 1894 [Sub ...
- BZOJ2588 Count on a tree DFS序+LCA+值域主席树
Count on a tree 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答 ...
- [SPOJ-COT]Count on a tree
[SPOJ-COT]Count on a tree 题面 You are given a tree with N nodes. The tree nodes are numbered from 1 t ...
- BZOJ2588 Count on a tree 【树上主席树】
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MB Submit: 7577 Solved: 185 ...
- 【SPOJ】Count On A Tree II(树上莫队)
[SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...
- BZOJ 2588 Spoj 10628 Count on a tree | 树上主席树
BZOJ 2588 Count on a tree 题面 求树上两点之间路径上第k大的点权. 题解 一开始看到这道题觉得是树剖,然后又听说是主席树,然后以为是主席树+树剖,差点没吓死-- 然后发现,如 ...
- 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 ...
- P2633 Count on a tree
P2633 Count on a tree 题意: 给定一棵 n 个节点的树,每个点有一个权值.有 m 个询问,每次给你 u,v,k,你需要回答 u xor last 和 v 这两个节点间第 k 小的 ...
- SP10707 COT2 - Count on a tree II
SP10707 COT2 - Count on a tree II 题意: 给定 n 个结点的树,每个结点有一种颜色. m 次询问,每次询问给出 u,v,回答 u,v 之间的路径上的结点的不同颜色数. ...
最新文章
- 测试方案_何小伟:ABTest测试方案
- (西瓜书)#版本空间与样本空间
- Nature调查 l 中国博士生们的科研围城
- 从零开始数据科学与机器学习算法-朴素贝叶斯-07
- TCP程序流程及服务器客户端
- ROS学习笔记1(配置ROS环境和创建工作空间)
- 【电子书】Head First Java
- 瓜瓜播放器android,瓜瓜视频播放器
- 智慧城管基础业务系统建设系统方案
- JAVA中小型医院信息管理系统源码 医院系统源码
- 决策树ID3算法实现与讨论(完整代码与数据)
- linux挂载移动硬盘 格式化_Linux下挂载移动硬盘(NTFS格式)
- V4L2视频采集的基本流程
- hbase scan超时设置_hbase scan limit 10
- python画简单的图形(结构,循环)
- 批处理登陆邮箱代码分析
- grep同时过滤多个条件
- html5核心ml5图片居中,HTML5图片居中的问题
- ellipsize实现跑马灯总结
- NERO刻录教程图解
热门文章
- 实验5_JPEG解码
- ROS Kinetic或ROS melodic下安装MoveIt!出现的问题:无法定位软件包 ros-kinetic-moveit-full或ros-melodic-moveit-full
- 【Tools】Modbus Poll 9安装详解
- 【Linux网络编程】网络字节序和地址转换
- 【Linux】一步一步学Linux——du命令(78)
- freetds php mssql 中文乱码,PHP读取mssql json数据中文乱码的解决办法
- 演讲者模式投影到幕布也看到备注_家用投影幕布怎么选?(看这一篇就明白了)...
- 在Linux虚拟机中添加多个ip地址
- 找到字符串中所有字母异位词—leetcode438
- Xcode 不用签名编译程序