题目链接:点击查看

题目大意:给出一棵树,每条边上都有一个权值,给出m个查询:a,b:问从点1到点a的唯一路径上,在边权小于等于b的边中选出边权最大的值输出,若没有符合条件的边则输出-1;

题目分析:时隔三个月再次重温这个题目,感觉这个题目真的就简单多了,直接剖完然后离线线段树做就行了,所以为了挑战一下自己,我选择用主席树写了一发,不得不说,这个题目内存卡的真死,权值的数据给到了1e9,本来想开32倍的主席树然后直接用线段树动态离散化的,结果第一发直接MLE了,看了一眼题目给的内存,只给了32M,开32倍的线段树就直接38M了,无奈,只能离散化一下了,还好这个题没卡我用vector离散化,最后31.7M险些飘过

这里和zx学长在讨论这个题的时候有点对主席树的小理解吧,我之前有点想当然的以为主席树都应该维护一个sum来判断是否有满足条件的区间,但其实并不然,就拿这个题为例,因为是要求点1到点u这条链上满足条件的最大值,所以我们只用维护一个最大值的主席树即可,并不用维护sum这个变量了,zx学长给我这么一点拨,我就想到若想求u-v这条边上满足条件的最大值的话,是不是就不太好用主席树来做了,zx学长只是给我留了一句话,可以用主席树做,只不过时间复杂度会带上个常数,emmm,说实话我想了很久也没想到该怎么实现,可能是我还太菜了,我现在对主席树的理解还是只会维护一个sum和,然后用sum解决第k大的问题以及大于等于或者小于等于k的数有多少个,要是真的让写从u-v上满足条件的最大值的话,我还是只会卑微的用线段树离线来写

希望过三个月再回顾现在写的这些内容,会感觉自己之前的理解都好幼稚,也希望能看到进步之后的自己,就像现在的自己看三个月之前的博客一样吧

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e5+100;int n;struct Node
{int to,w,next;
}edge[N<<1];int head[N],tot;void addedge(int u,int v,int w)//链式前向星
{edge[tot].to=v;edge[tot].w=w;edge[tot].next=head[u];head[u]=tot++;edge[tot].to=u;edge[tot].w=w;edge[tot].next=head[v];head[v]=tot++;
}vector<int>num;//离散化蛹int getnum(int x)//离散化用
{return lower_bound(num.begin(),num.end(),x)-num.begin()+1;
}struct tree
{int l,r,mmax;
}tree[N*32];//主席树维护最大值int root[N],cnt;void insert(int pre,int& cur,int l,int r,int pos)
{cur=++cnt;tree[cur]=tree[pre];tree[cur].mmax=max(tree[pre].mmax,pos);if(l==r)return;int mid=l+r>>1;if(mid>=pos)insert(tree[pre].l,tree[cur].l,l,mid,pos);elseinsert(tree[pre].r,tree[cur].r,mid+1,r,pos);
}int query(int cur,int l,int r,int ll,int rr)//l,r:当前区间 ll,rr:目标区间
{if(l>=ll&&r<=rr)return tree[cur].mmax;if(r<ll||l>rr)return 0;int mid=l+r>>1;return max(query(tree[cur].l,l,mid,ll,rr),query(tree[cur].r,mid+1,r,ll,rr));
}void dfs(int u,int f)
{for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;if(v==f)continue;insert(root[u],root[v],1,num.size(),getnum(w));dfs(v,u);}
}void init()
{for(int i=1;i<=n;i++)head[i]=-1;cnt=tot=0;
}int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);int w;cin>>w;while(w--){scanf("%d",&n);init();num.clear();for(int i=1;i<n;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);addedge(u,v,w);num.push_back(w);}sort(num.begin(),num.end());num.erase(unique(num.begin(),num.end()),num.end());dfs(1,0);int m;scanf("%d",&m);while(m--){int x,y;scanf("%d%d",&x,&y);int pos=upper_bound(num.begin(),num.end(),y)-num.begin();int ans=query(root[x],1,num.size(),1,pos);if(ans)printf("%d\n",num[ans-1]);elseprintf("%d\n",-1);}}return 0;
}

HDU - 3804 Query on a tree(主席树维护最大值+离散化)相关推荐

  1. HDU - 3804 Query on a tree(树链剖分+线段树+离线处理)

    题目链接:点击查看 题目大意:给出一棵树,每条边上都有一个权值,给出m个查询:a,b:问从点1到点a的唯一路径上,在边权小于等于b的边中选出边权最大的值输出,若没有符合条件的边则输出-1: 题目分析: ...

  2. SPOJ 10628 Count on a tree 主席树 附数据生成器

    很奇怪的题啊,感觉思路和别人一样,但是我得用快速IO才能AC--不然就T 没用快速output,只用了快速input 而且居然限制代码长度...代码要短于6000B,我改了好久啊 题目大意:给一棵树, ...

  3. CodeForces 464E The Classic Problem | 呆克斯歘 主席树维护高精度

    题意描述 有一个\(n\)点\(m\)边的无向图,第\(i\)条边的边权是\(2^{a_i}\).求点\(s\)到点\(t\)的最短路长度(对\(10^9 + 7\)取模). 题解 思路很简单--用主 ...

  4. hdu 4605 Magic Ball Game (在线主席树/离线树状数组)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4605 题意: 有一颗树,根节点为1,每一个节点要么有两个子节点,要么没有,每个节点都有一个权值wi .然后,有一个球,附带值x . 球 ...

  5. HDU - 6704 K-th occurrence (后缀数组+主席树)

    题目链接 题意 QQQ次询问,每次询问求SSS的子串出现KKK次的位置 思路 刚开始想的是AC自动机,但是建自动机会超时,后来学长想到后缀数组+主席树的做法Orz...Orz...Orz... 出现K ...

  6. SPOJ 375. Query on a tree (树链剖分)

    题目链接: http://www.spoj.com/problems/QTREE/ 375. Query on a tree Problem code: QTREE You are given a t ...

  7. XXI Open Cup. Grand Prix of Korea I. Query On A Tree 17 树剖 + 二分 + 树带权重心

    传送门 文章目录 题意: 思路: 题意: 给你一棵树,每棵树初始权值都为000,现在给你两个操作: (1)(1)(1)将uuu的子树权值全部加111. (2)(2)(2)将(u,v)(u,v)(u,v ...

  8. bzoj2588: Spoj 10628. Count on a tree 主席树

    在每一个点的父亲做主席树,每次访问时用两个点的和减去其LCA和LCA父亲的和即可. #include<bits/stdc++.h> using namespace std; inline ...

  9. HDU 4348 To the moon(主席树区间修改)

    题意 给你一个区间,支持如下操作: 在一段区间内加上一个值,并生成一个历史版本 查询某个版本下一段区间内的和 回到一个历史版本上并舍弃之后的版本 做法 这就是主席树区间修改裸题啦QwQ 上一篇博客我讲 ...

最新文章

  1. cli vue 卸载,vue Cli 环境删除与重装教程 - 版本文档
  2. s3 aws_您需要了解的有关AWS S3的所有信息
  3. SQL语言之子查询(Oracle)
  4. php合同在线签约功能_【市场在线】杭汽辅机实现海外发电市场重大突破 —成功签约阿联酋Fujairah F3 IPP项目表冷器合同...
  5. 在php中页面布局 3列左右侧固定中间自适应居中,css三列布局--两边固定中间自适应和中间固定两边自适应...
  6. flask 知识点总结
  7. 深入理解InnoDB(5)-文件系统
  8. 启动马达接线实物图_东元伺服驱动马达
  9. python画猫和老鼠_观察者模式(猫与老鼠的故事!)
  10. HttpClient 入门与正确使用姿势
  11. mysql没有索引删除一亿数据_mysql数据库如何实现亿级数据快速清理
  12. 阿里云云计算 52在线实验--云监控初体验
  13. bzoj3514 Codechef MARCH14 GERALD07加强版 lct预处理+主席树
  14. chrome怎么安装java插件下载_java插件下载如何将JAVA插件支持Chrome
  15. 调用python-nmap实现扫描局域网存活主机
  16. 翻译来自HiDDeN网络架构-Lifeifei
  17. edg击败we视频_edg击败we视频_LPL夏季赛:EDG零封V5获三连胜 OMG2-1击败WE
  18. mysql 常用函数
  19. Dream-hacking 造梦工程与脑波艺术
  20. Discuz 论坛优化

热门文章

  1. Redis集群在线分片
  2. 初识ES-安装IK分词器
  3. SpringBoot自动配置【源码分析】-初始加载自动配置类
  4. springAop和AspectJ的关系
  5. Synchronized结合Java Object对象中的 wait,notify,notifyAll
  6. Redis中的Lua脚本超时
  7. 自定义线程池-线程池类和测试类编写
  8. logback 的拆分 Appender
  9. Azkaban编译和安装模式
  10. 用户操作-用户详情查询流程分析