https://www.lydsy.com/JudgeOnline/problem.php?id=4009

https://www.luogu.org/problemnew/show/P3242

https://loj.ac/problem/2113

风见幽香非常喜欢玩一个叫做 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 小的那个盘子,每个盘子可重复使用(没有使用次数的上限:一个盘子接完一个水果后,后面还可继续接其他水果,只要它是水果路径的子路径)。幽香认为这个游戏很难,你能轻松解决给她看吗?

因为预先做过LOJ6276:果树,不难想到对于树上路径的处理方法和它一样。

那么对于每个盘子用dfs序表示的路径点(u,v),分两种情况:

1.u和v有一个不同于二者的lca

显然它能接到的水果的两端一个在u的子树中,一个在v的子树中。

2.v是u的祖先。

显然它能接到的水果的两端一个在u的子树中,一个在v的子树的补集(包括v)中。

那么对于一个水果的路径点,如果在这个矩形当中,就说明这个水果能够被哪些盘子所接。

那么处理完之后,显然不能用主席树来解决第k大(如果能当我没说),于是我们整体二分一下即可。

……这是我最开始做这道题的想法,但是码了4h后对此绝望,对着数据参着题解调到现在才过。

说几个(我)容易错的点:

1.区间第k小,所以不是第k大的做法,注意答案在左区间还是右区间。

2.用扫描线存的时候注意空间开大点,另外上边界不要忘了+1

3.矩形的x和y坐标以及水果的x和y坐标存法(顺序)一定要相同。

代码138行凑和吧,但是细节真心多。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=4e4+;
const int B=;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct path{
int to,nxt;
}e[N*];
struct dish{
int x1,x2,y,c,w;
}d[*N],td1[*N],td2[*N];
struct fruit{
int x,y,k,id;
}f[N],tf1[N],tf2[N];
int m,b[N],ans[N],tr[N],c[N];
int anc[N][B+],dep[N],size[N];
int n,p,q,cnt,head[N],pos[N],tot;
inline bool cmp1(dish a,dish b){
return a.y<b.y;
}
inline bool cmp2(fruit a,fruit b){
return a.y<b.y;
}
inline void add(int u,int v){
e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt;
}
void dfs(int u){
pos[u]=++tot;size[u]=;
dep[u]=dep[anc[u][]]+;
for(int i=;i<=B;++i)
anc[u][i]=anc[anc[u][i-]][i-];
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v!=anc[u][]){
anc[v][]=u;
dfs(v);
size[u]+=size[v];
}
}
}
inline int LCA(int i,int j){
if(dep[i]<dep[j])swap(i,j);
for(int k=B;k>=;--k)
if(dep[anc[i][k]]>=dep[j])i=anc[i][k];
if(i==j)return i;
for(int k=B;k>=;--k)
if(anc[i][k]!=anc[j][k])
i=anc[i][k],j=anc[j][k];
return anc[i][];
}
inline int lowbit(int t){return t&(-t);}
inline void ins(int x,int y){
for(int i=x;i<=n;i+=lowbit(i))tr[i]+=y;
}
inline int qry(int x){
int res=;
for(int i=x;i;i-=lowbit(i))res+=tr[i];
return res;
}
inline void mdy(int l,int r,int w){
ins(l,w);ins(r+,-w);
}
void solve(int L,int R,int s,int t,int l,int r){
if(L>R||s>t)return;
if(l==r){
for(int i=L;i<=R;++i)ans[f[i].id]=c[l];
return;
}
int id1=,id2=,if1=,if2=,mid=(l+r)>>,j=s;
for(int i=L;i<=R;++i){
for(;j<=t&&d[j].y<=f[i].y;++j){
if(d[j].c>c[mid])td1[id1++]=d[j];
else mdy(d[j].x1,d[j].x2,d[j].w),td2[id2++]=d[j];
}
int tmp=qry(f[i].x);
if(f[i].k>tmp)f[i].k-=tmp,tf1[if1++]=f[i];
else tf2[if2++]=f[i];
}
for(;j<=t;++j){
if(d[j].c>c[mid])td1[id1++]=d[j];
else mdy(d[j].x1,d[j].x2,d[j].w),td2[id2++]=d[j];
}
int mdst=s+id1,MID=L+if1;
for(int i=s;i<mdst;++i)d[i]=td1[i-s];
for(int i=mdst;i<=t;++i)d[i]=td2[i-mdst];
for(int i=L;i<MID;++i)f[i]=tf1[i-L];
for(int i=MID;i<=R;++i)f[i]=tf2[i-MID];
solve(L,MID-,s,mdst-,mid+,r);solve(MID,R,mdst,t,l,mid);
return;
}
int main(){
n=read(),p=read(),q=read();
for(int i=;i<n;++i){
int u=read(),v=read();
add(u,v);add(v,u);
}
dfs();
for(int i=;i<=p;++i){
int u=read(),v=read();c[i]=read();
if(pos[u]>pos[v])swap(u,v);
int lca=LCA(u,v);
if(lca!=u&&lca!=v){
d[++m]=(dish){pos[u],pos[u]+size[u]-,pos[v],c[i],};
d[++m]=(dish){pos[u],pos[u]+size[u]-,pos[v]+size[v],c[i],-};
}else{
int t=v;
for(int k=B;k>=;--k)
if(dep[anc[t][k]]>=dep[u]+)t=anc[t][k];
d[++m]=(dish){,pos[t]-,pos[v],c[i],};
d[++m]=(dish){,pos[t]-,pos[v]+size[v],c[i],-};
d[++m]=(dish){pos[v],pos[v]+size[v]-,pos[t]+size[t],c[i],};
d[++m]=(dish){pos[v],pos[v]+size[v]-,n+,c[i],-};
}
}
for(int i=;i<=q;++i){
int u=read(),v=read(),k=read();
if(pos[u]>pos[v])swap(u,v);
f[i]=(fruit){pos[u],pos[v],k,i};
}
sort(d+,d+m+,cmp1);
sort(f+,f+q+,cmp2);
sort(c+,c+p+);
int len=unique(c+,c+p+)-c-;
solve(,q,,m,,len);
for(int i=;i<=q;++i)printf("%d\n",ans[i]);
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ4009 & 洛谷3242 & LOJ2113:[HNOI2015]接水果——题解的更多相关文章

  1. 【BZOJ4009_洛谷3242】[HNOI2015] 接水果(整体二分)

    题目: 洛谷 3242 分析: 明确题意:在一棵树上给定若干权值为 \(w\) 的路径 \((u,v)\) (盘子),每次给定 \((a,b)\) (水果),询问所有满足 \((u,v)\) 被 \( ...

  2. 洛谷P1854 花店橱窗布置 分析+题解代码

    洛谷P1854 花店橱窗布置 分析+题解代码 蒟蒻的第一道提高+/省选-,纪念一下. 题目描述: 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定 ...

  3. HAOI2006 (洛谷P2341)受欢迎的牛 题解

    HAOI2006 (洛谷P2341)受欢迎的牛 题解 题目描述 友情链接原题 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之 ...

  4. 洛谷P3412 仓鼠找$Sugar\ II$题解(期望+统计论?)

    洛谷P3412 仓鼠找\(Sugar\ II\)题解(期望+统计论?) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327573 原题链接:洛谷P3412 ...

  5. 洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速$dp\&Floyd$)

    洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速\(dp\&Floyd\)) 标签:题解 阅读体验:https://zybuluo.com/Junl ...

  6. 【洛谷3239_BZOJ4008】[HNOI2015] 亚瑟王(期望 DP)

    题目: 洛谷 3239 分析: 卡牌造成的伤害是互相独立的,所以 \(ans=\sum f_i\cdot d_i\) ,其中 \(f_i\) 表示第 \(i\) 张牌 在整局游戏中 发动技能的概率.那 ...

  7. BZOJ4946 & 洛谷3826 & UOJ318:[NOI2017]蔬菜——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4946 https://www.luogu.org/problemnew/show/P3826 ht ...

  8. 洛谷 P1146 【硬币翻转】题解

    很久很久之前做过的一道题 翻n-1枚硬币,就是有一枚不翻,也可以理解为翻一枚 直接上程序,看程序说话 #include<iostream> using namespace std; ; b ...

  9. 洛谷P1972 [SDOI2009]HH的项链 题解

    [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不 ...

随机推荐

  1. Linux命令应用大词典-第7章 字符串、文件和命令查找

    7.1 grep:字符串.文件和命令的查找 7.2 egrep:在文件或标准输入中查找模式 7.3 fgrep:在每个文件或是标准输入中查找模式 7.4 find:列出文件系统内符合条件的文件 7.5 ...

  2. <cassert>

    文件名:  <cassert> (assert.h) 这是一个C语言的诊断库,assert.h文件中定义了一个可作为标准调试工具的宏函数: assert ; 下面介绍这个宏函数:asser ...

  3. zookeeper应用:屏障、队列、分布式锁

    zookeeper工具类: 获取连接实例:创建节点:获取子节点:设置节点数据:获取节点数据:访问控制等. package org.windwant.zookeeper; import org.apac ...

  4. C#-返回相对时间函数

    在公司一直做前端,经理叫我写一个后端函数,要求是: 参数:DateTime--传入任意时间类型返回:string --返回传入参数时间与当前时间的相对时间字符串,如:3天前,1小时前,5分钟前. 注意 ...

  5. linux NULL 的定义

    #undef NULL #if defined(__cplusplus) #define NULL 0 #else #define NULL ((void *)0) #endif

  6. *转载 Tarjan有向图详解

    注意! 文章转自:https://www.cnblogs.com/liwenchi/p/7259306.html,如有造成任何侵权行为,请与我联系.我会在第一时间删除. 不过说实话,这大佬写的真的强, ...

  7. java.net.ProtocolException: Server redirected too many times

    网页爬虫时,原来正常的代码,可能是因为网站做了cookie校验处理,报异常:java.net.ProtocolException: Server redirected too many times 表 ...

  8. HDU 3726 Graph and Queries(平衡二叉树)(2010 Asia Tianjin Regional Contest)

    Description You are given an undirected graph with N vertexes and M edges. Every vertex in this grap ...

  9. Mr. Frog’s Game(模拟连连看)

    Description One day, Mr. Frog is playing Link Game (Lian Lian Kan in Chinese). In this game, if you ...

  10. TCP系列35—窗口管理&流控—9、紧急机制

    一.概述 我们在最开始介绍TCP头结构的时候,里面有个URG的标志位,还有一个Urgent Pointer的16bits字段.当URG标志位有效的时候,Urgent Poinert用来指示紧急数据的相 ...