[HNOI2015]接水果
题目描述
风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果。由于她已经DT FC 了The big black, 她觉得这个游戏太简单了,于是发明了一个更加难的版本。
首先有一个地图,是一棵由 n 个顶点、n-1 条边组成的树(例如图 1给出的树包含 8 个顶点、7 条边)。
这颗树上有 P 个盘子,每个盘子实际上是一条路径(例如图 1 中顶点 6 到顶点 8 的路径),并且每个盘子还有一个权值。第 i 个盘子就是顶点a_i到顶点b_i的路径(由于是树,所以从a_i到b_i的路径是唯一的),权值为c_i。
接下来依次会有Q个水果掉下来,每个水果本质上也是一条路径,第i 个水果是从顶点 u_i 到顶点v_i 的路径。
幽香每次需要选择一个盘子去接当前的水果:一个盘子能接住一个水果,当且仅当盘子的路径是水果的路径的子路径(例如图1中从 3到7 的路径是从1到8的路径的子路径)。这里规定:从a 到b的路径与从b到 a的路径是同一条路径。
当然为了提高难度,对于第 i 个水果,你需要选择能接住它的所有盘子中,权值第 k_i 小的那个盘子,每个盘子可重复使用(没有使用次数的上限:一个盘子接完一个水果后,后面还可继续接其他水果,只要它是水果路径的子路径)。幽香认为这个游戏很难,你能轻松解决给她看吗? < width="395" height="212" alt="" />
输入输出格式
输入格式:
第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数。 接下来n-1 行,每行两个数 a、b,表示树上的a和b 之间有一条边。树中顶点按1到 n标号。 接下来 P 行,每行三个数 a、b、c,表示路径为 a 到 b、权值为 c 的盘子,其中0<=c<=10^9,a不等于b。 接下来Q行,每行三个数 u、v、k,表示路径为 u到 v的水果,其中 u不等于v,你需要选择第 k小的盘子,第k 小一定存在。
输出格式:
对于每个果子,输出一行表示选择的盘子的权值。
输入输出样例
10 10 10 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 3 2 217394434 10 7 13022269 6 7 283254485 6 8 333042360 4 6 442139372 8 3 225045590 10 4 922205209 10 8 808296330 9 2 486331361 4 9 551176338 1 8 5 3 8 3 3 8 4 1 8 3 4 8 1 2 3 1 2 3 1 2 3 1 2 4 1 1 4 1
442139372 333042360 442139372 283254485 283254485 217394434 217394434 217394434 217394434 217394434http://www.cnblogs.com/NaVi-Awson/p/8150418.html
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 struct Node 8 { 9 int next,to; 10 }edge[100001]; 11 struct FFF 12 { 13 int x1,x2,y1,y2,k; 14 }opt[100001]; 15 struct ZYYS 16 { 17 int x,y,k,id; 18 }query[80001],qa[80001],qb[80001]; 19 struct ALUGE 20 { 21 int x,y1,y2,d,id; 22 }event[200001]; 23 int head[80001],num,dfn[80001],cnt,size[80001],n,son[80001],dep[80001],pa[80001],last[80001],top[80001]; 24 int c[80001],ans[80001],sum[80001],p,q,cntp; 25 bool cmpe(ALUGE a,ALUGE b) 26 { 27 if (a.x==b.x) return a.id<b.id; 28 return a.x<b.x; 29 } 30 bool cmpp(FFF a,FFF b) 31 { 32 return a.k<b.k; 33 } 34 bool cmpq(ZYYS a,ZYYS b) 35 { 36 return a.x<b.x; 37 } 38 void add(int u,int v) 39 { 40 num++; 41 edge[num].next=head[u]; 42 head[u]=num; 43 edge[num].to=v; 44 } 45 void dfs1(int x,int fa) 46 {int i; 47 size[x]=1; 48 son[x]=0; 49 for (i=head[x];i;i=edge[i].next) 50 { 51 int v=edge[i].to; 52 if (v!=fa) 53 { 54 dep[v]=dep[x]+1;pa[v]=x; 55 dfs1(v,x); 56 size[x]+=size[v]; 57 if (size[v]>=size[son[x]]) son[x]=v; 58 } 59 } 60 last[x]=cnt; 61 } 62 void dfs2(int x,int tp,int fa) 63 {int i; 64 top[x]=tp; 65 dfn[x]=++cnt; 66 if (son[x]) dfs2(son[x],tp,x); 67 for (i=head[x];i;i=edge[i].next) 68 { 69 int v=edge[i].to; 70 if (v!=son[x]&&v!=fa) 71 dfs2(v,v,x); 72 } 73 last[x]=cnt; 74 } 75 int LCA(int u,int v) 76 { 77 while (top[u]!=top[v]) 78 { 79 if (dep[top[u]]<dep[top[v]]) swap(u,v); 80 u=pa[top[u]]; 81 } 82 if (dep[u]<dep[v]) return u; 83 else return v; 84 } 85 int getson(int u,int v) 86 { 87 int last=0; 88 while (top[v]!=top[u]) 89 { 90 last=top[v]; 91 v=pa[last]; 92 } 93 if (u==v) return last; 94 return son[u]; 95 } 96 void update(int x,int d1,int y,int d2) 97 { 98 while (x<=n) 99 { 100 c[x]+=d1; 101 x+=(x&(-x)); 102 } 103 y++; 104 while (y<=n) 105 { 106 c[y]+=d2; 107 y+=(y&(-y)); 108 } 109 } 110 int get_sum(int x) 111 { 112 int s=0; 113 while (x) 114 { 115 s+=c[x]; 116 x-=x&(-x); 117 } 118 return s; 119 } 120 void solve(int l,int r,int st,int ed) 121 {int i; 122 if (st>ed) return; 123 if (l==r) 124 { 125 for (i=st;i<=ed;i++) 126 ans[query[i].id]=opt[l].k; 127 return; 128 } 129 int mid=(l+r)/2; 130 int siz=0; 131 for (i=l;i<=mid;i++) 132 { 133 event[++siz]=(ALUGE){opt[i].x1,opt[i].y1,opt[i].y2,1,0}; 134 event[++siz]=(ALUGE){opt[i].x2,opt[i].y1,opt[i].y2,-1,n+1}; 135 } 136 for (i=st;i<=ed;i++) 137 { 138 event[++siz]=(ALUGE){query[i].x,query[i].y,0,0,i}; 139 } 140 sort(event+1,event+siz+1,cmpe); 141 memset(c,0,sizeof(c)); 142 for (i=1;i<=siz;i++) 143 { 144 if (event[i].id<=ed&&event[i].id>=st) sum[event[i].id]=get_sum(event[i].y1); 145 else update(event[i].y1,event[i].d,event[i].y2,-event[i].d); 146 } 147 int cnta=0,cntb=0; 148 for (i=st;i<=ed;i++) 149 { 150 if (sum[i]>=query[i].k) qa[++cnta]=query[i]; 151 else qb[++cntb]=query[i],qb[cntb].k-=sum[i]; 152 } 153 for (i=st;i<=st+cnta-1;i++) 154 query[i]=qa[i-st+1]; 155 for (i=st+cnta;i<=ed;i++) 156 query[i]=qb[i-st-cnta+1]; 157 solve(l,mid,st,st+cnta-1); 158 solve(mid+1,r,st+cnta,ed); 159 } 160 int main() 161 { 162 int i,u,v,d; 163 cin>>n>>p>>q; 164 for (i=1;i<=n-1;i++) 165 { 166 scanf("%d%d",&u,&v); 167 add(u,v);add(v,u); 168 } 169 dfs1(1,0);dfs2(1,1,0); 170 for (i=1;i<=p;i++) 171 { 172 scanf("%d%d%d",&u,&v,&d); 173 if (dfn[u]>dfn[v]) swap(u,v); 174 int w=LCA(u,v); 175 if (u==w) 176 { 177 w=getson(u,v); 178 if (dfn[w]>1) opt[++cntp]=(FFF){1,dfn[w]-1,dfn[v],last[v],d}; 179 if (last[w]<n) opt[++cntp]=(FFF){dfn[v],last[v],last[w]+1,n,d}; 180 } 181 else 182 { 183 opt[++cntp]=(FFF){dfn[u],last[u],dfn[v],last[v],d}; 184 } 185 } 186 p=cntp; 187 for (i=1;i<=q;i++) 188 { 189 scanf("%d%d%d",&u,&v,&d); 190 if (dfn[u]>dfn[v]) swap(u,v); 191 query[i]=(ZYYS){dfn[u],dfn[v],d,i}; 192 } 193 sort(opt+1,opt+p+1,cmpp); 194 sort(query+1,query+q+1,cmpq); 195 solve(1,p,1,q); 196 for (i=1;i<=q;i++) 197 printf("%d\n",ans[i]); 198 }
转载于:https://www.cnblogs.com/Y-E-T-I/p/8176196.html
[HNOI2015]接水果相关推荐
- P3242 [HNOI2015] 接水果(整体二分、扫描线)
P3242 [HNOI2015] 接水果 给定一棵树,定义给定了ppp个盘子,每个盘子是树上u,vu, vu,v两点的路径,且盘子有权值,定义水果,水果也是树上u,vu, vu,v两点间的路径. 有q ...
- [洛谷P3242] [HNOI2015]接水果
洛谷题目链接:[HNOI2015]接水果 题目描述 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, 她觉得这个游戏太简 ...
- 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组
题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...
- P3242 [HNOI2015] 接水果(整体二分、扫描线、dfs序)
解析 一道有点毒瘤的题 也是一道感觉真的可以出现在考场上的很综合的题 做的还可以 除了一开始把盘子和水果看反白写了各树套树之外 为什么盘子是水果的子路径啊 由于是做专题爬过来的多次询问区间第k小,想到 ...
- bzoj4009: [HNOI2015]接水果(整体二分)
题目描述 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, 她觉得这个游戏太简单了,于是发明了一个更加难的版本. 首先有 ...
- bzoj 4009: [HNOI2015]接水果 整体二分+k-d tree
Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果. 由于她已经DT FC 了The big black, 她觉得这个游戏太简单了,于是发明了一个更 加 ...
- [HNOI2015] 接水果(倍增 + 整体二分)
problem luogu-P3242 solution 本题的难点在于如何判定路径之间是否覆盖. 这里我们尝试树常见的 dfs\text{dfs}dfs 序. 考虑 x−yx-yx−y 路径如果要覆 ...
- 【Luogu】 P3242 [HNOI2015] 接水果
题目链接 点击打开链接 题目解法 我们发现一段路径包含另一条不好做,但是被包含的关系就比较简单 对于每个盘子,我们可以分成 2 类情况,这里可以预处理出dfn序,令st[u]为进入u的时间,ed[u] ...
- BZOJ 4009 HNOI2015 接水果 树套树
题目大意:给定一棵树和m<script type="math/tex" id="MathJax-Element-32">m</script&g ...
最新文章
- 谈谈Linux打补丁的原理以及如何判别打补丁的错误 --- 从补丁学内核
- php数据库可转java数据库,php转java 系列2 Spring boo 链接数据库jdbc
- 清翔电子单片机原理图stc89c52_1000. 电子编程入门到工程师--从看得到开始
- 小米公布Q1手机出货量:驳斥暴跌谣言
- 引用和指针的区别[zz]
- 如何免费下载百度文库,豆丁网等付费文章
- Linux中安装VIM命令
- 微信小程序echarts问题整理与解决
- MySQL —— 查询升序和降序
- 积木报表-报表常用操作
- Fanuc机器人奇异点问题解决方法(适用于roboguide)
- UEFI和传统引导的区别有哪些
- 生产环境lepus部署 监控MySQL
- Vue按回车键进行搜索
- 基于Keras版本YOLOV7模型的锂电池自燃预警烟雾检测实践
- argmax与max的区别
- 苹果13系统锁屏延迟_iPhone锁屏有延迟怎么办 锁屏延迟问题解决方法
- 10种相亲交友源码客户端存储,值得一看
- 个人认为比较好的几个IT技术论坛
- python物理模拟_如何在Python 游戏中模拟引力
热门文章
- 在LoadRunner向远程Linux/Unix执行命令行并收集性能数据
- 初中计算机应用教什么,信息技术在初中数学教学中的应用
- python与pyqt5_【Python开发】PyQt5应用与实践
- java同步互斥功能检测_猿考研之操作系统篇三(进程同步,管程,死锁)
- redis实现轮询算法_用redis实现支持优先级的消息队列
- linux查看服务依赖关系,服务管理(1)
- python进程socket通信_Python Socket TCP双端聊天功能实现过程详解
- python中write的用法_Python中操作文件之write()方法的使用教程
- vue ts prop
- Python 代码性能优化技巧