练码力的好题.
题目链接


首先容易想到一条路径代表二维平面上的一个点.
在树上,那就求出\(dfs\)序.
我们令\(L_u=dfn[u],R_u=dfn[u]+size[u]-1\)
一条\(u\rightarrow v\)的路径可以被映射到一个点\((L_u,R_u)\)上

假设有一个盘子\(u\rightarrow v\),我们分两种情况讨论.
如果\(lca(u,v)\)不为\(u\),且不为\(v\),那么只要水果一个端点在\(u\)的子树内,另一个端点在\(v\)的子树内即可.
因此水果路径是属于\(\{(L_u,L_v),(R_u,R_v)\}\)这个矩形的.
假设\(lca(u,v)=u\),那么找到\(u\)的一个儿子在\(u\rightarrow v\)的路径上,设它为\(x\),那么只要一个点在\(v\)的子树内,一个点不在\(x\)的子树内即可.
这是两个矩形:\(\{(1,L_v),(L_x-1,R_v)\}\)和\(\{(R_x+1,L_v),(n,R_v)\}\).

那么我们把这个题转化成这样:
有若干个矩形,每次询问一个点,求覆盖它的所有矩形中权值第\(k\)小的.
我们可以整体二分.

代码如下:
还挺短
好吧其实大力压行过了\(QAQ\)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#define N (80010)
#define M (200010)
#define inf (0x7f7f7f7f)
#define rg register int
#define Label puts("NAIVE")
#define spa print(' ')
#define ent print('\n')
#define rand() (((rand())<<(16))^(rand()))
typedef long double ld;
typedef long long LL;
typedef unsigned long long ull;
using namespace std;
inline char read(){static const int IN_LEN=1000000;static char buf[IN_LEN],*s,*t;return (s==t?t=(s=buf)+fread(buf,1,IN_LEN,stdin),(s==t?-1:*s++):*s++);
}
template<class T>
inline void read(T &x){static bool iosig;static char c;for(iosig=false,c=read();!isdigit(c);c=read()){if(c=='-')iosig=true;if(c==-1)return;}for(x=0;isdigit(c);c=read())x=((x+(x<<2))<<1)+(c^'0');if(iosig)x=-x;
}
inline char readchar(){static char c;for(c=read();!isalpha(c)&&!isdigit(c);c=read())if(c==-1)return 0;return c;
}
const int OUT_LEN = 10000000;
char obuf[OUT_LEN],*ooh=obuf;
inline void print(char c) {if(ooh==obuf+OUT_LEN)fwrite(obuf,1,OUT_LEN,stdout),ooh=obuf;*ooh++=c;
}
template<class T>
inline void print(T x){static int buf[30],cnt;if(x==0)print('0');else{if(x<0)print('-'),x=-x;for(cnt=0;x;x/=10)buf[++cnt]=x%10+48;while(cnt)print((char)buf[cnt--]);}
}
inline void flush(){fwrite(obuf,1,ooh-obuf,stdout);}
struct que{int x,y,w,id;friend bool operator <(que a,que b){return a.x<b.x;}
}q[M],q1[M],q2[M];
struct chg{int ly,ry,x,w,tag,id;friend bool operator <(chg a,chg b){return a.w<b.w||a.w==b.w&&a.id<b.id;}
}a[N];
int n,m,Q,E,fi[N],ne[M],b[M],dfn[N],ind,siz[N],f[N][17],cnt,dep[N],ans[N];
struct BIT{int c[M];void add(int x,int w){for(;x<=n;x+=(x&-x))c[x]+=w;}void add(int l,int r,int w){add(l,w),add(r+1,-w);}int query(int x){int ans=0;for(;x;x-=(x&-x))ans+=c[x];return ans;}
}T;
void add(int x,int y){ne[++E]=fi[x],fi[x]=E,b[E]=y;}
void add_line(int lx,int ly,int rx,int ry,int w){if(lx>ly)swap(lx,ly),swap(rx,ry);a[++cnt]=(chg){ly,ry,lx,w,1,cnt};a[++cnt]=(chg){ly,ry,rx+1,w,-1,cnt};
}
void dfs(int u,int pre){dfn[u]=++ind,siz[u]=1,f[u][0]=pre;for(int i=fi[u];i;i=ne[i]){int v=b[i];if(v==pre)continue;dep[v]=dep[u]+1,dfs(v,u),siz[u]+=siz[v];}
}
void INIT(){dfs(1,0);for(int i=1;i<=16;i++)for(int j=1;j<=n;j++)f[j][i]=f[f[j][i-1]][i-1];
}
int lca(int x,int y){if(dep[x]<dep[y])swap(x,y);int k=dep[x]-dep[y];for(int i=16;~i;i--)if(k&(1<<i))x=f[x][i];if(x==y)return x;for(int i=16;~i;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];if(x==y)return x;else return f[x][0];
}
int find(int x,int fa){int k=dep[x]-dep[fa]-1;for(int i=16;~i;i--)if(k&(1<<i))x=f[x][i];return x;
}
bool cmp(chg a,chg b){return a.x<b.x||a.x==b.x&&a.id<b.id;}
void solve(int L,int R,int l,int r){if(L>R)return;if(l+1>=r){for(int i=L;i<=R;i++)ans[q[i].id]=a[l].w;return;}int mid=(l+r)>>1,len=0,len1=0;if(mid&1)mid++;sort(a+l,a+mid+1,cmp);for(int i=l,j=L;i<=mid;i++){for(;a[i].x>q[j].x&&j<=R;j++){int x=T.query(q[j].y);if(x>=q[j].w)q1[++len]=q[j];else q2[++len1]=q[j],q2[len1].w-=x;}T.add(a[i].ly,a[i].ry,a[i].tag);if(i==mid)for(;j<=R;j++)q2[++len1]=q[j];}sort(a+l,a+mid+1);for(int i=1;i<=len;i++)q[L+i-1]=q1[i];for(int i=1;i<=len1;i++)q[L+len+i-1]=q2[i];solve(L,L+len-1,l,mid),solve(L+len,R,mid+1,r);
}
int main(){read(n),read(m),read(Q);for(int i=1,x,y;i<n;i++)read(x),read(y),add(x,y),add(y,x);INIT();for(int i=1,x,y,w;i<=m;i++){read(x),read(y),read(w);int rt=lca(x,y);if(rt==x||rt==y){if(rt==y)swap(x,y); int T=find(y,x);if(1<=dfn[T]-1)add_line(1,dfn[y],dfn[T]-1,dfn[y]+siz[y]-1,w);if(dfn[T]+siz[T]<=n)add_line(dfn[T]+siz[T],dfn[y],n,dfn[y]+siz[y]-1,w);}else add_line(dfn[x],dfn[y],dfn[x]+siz[x]-1,dfn[y]+siz[y]-1,w);}for(int i=1,x,y,K;i<=Q;i++){read(x),read(y),read(K);if(dfn[x]>dfn[y])swap(x,y);q[i]=(que){dfn[x],dfn[y],K,i};}sort(a+1,a+cnt+1),sort(q+1,q+Q+1),solve(1,Q,1,cnt);for(int i=1;i<=Q;i++)print(ans[i]),ent;return flush(),0;
}

转载于:https://www.cnblogs.com/Romeolong/p/10195956.html

HNOI2015 接水果相关推荐

  1. P3242 [HNOI2015] 接水果(整体二分、扫描线)

    P3242 [HNOI2015] 接水果 给定一棵树,定义给定了ppp个盘子,每个盘子是树上u,vu, vu,v两点的路径,且盘子有权值,定义水果,水果也是树上u,vu, vu,v两点间的路径. 有q ...

  2. [洛谷P3242] [HNOI2015]接水果

    洛谷题目链接:[HNOI2015]接水果 题目描述 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, 她觉得这个游戏太简 ...

  3. [HNOI2015]接水果

    题目描述 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, 她觉得这个游戏太简单了,于是发明了一个更加难的版本. 首先有 ...

  4. 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组

    题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...

  5. P3242 [HNOI2015] 接水果(整体二分、扫描线、dfs序)

    解析 一道有点毒瘤的题 也是一道感觉真的可以出现在考场上的很综合的题 做的还可以 除了一开始把盘子和水果看反白写了各树套树之外 为什么盘子是水果的子路径啊 由于是做专题爬过来的多次询问区间第k小,想到 ...

  6. bzoj4009: [HNOI2015]接水果(整体二分)

    题目描述 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, 她觉得这个游戏太简单了,于是发明了一个更加难的版本. 首先有 ...

  7. bzoj 4009: [HNOI2015]接水果 整体二分+k-d tree

    Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果. 由于她已经DT FC 了The big black, 她觉得这个游戏太简单了,于是发明了一个更 加 ...

  8. [HNOI2015] 接水果(倍增 + 整体二分)

    problem luogu-P3242 solution 本题的难点在于如何判定路径之间是否覆盖. 这里我们尝试树常见的 dfs\text{dfs}dfs 序. 考虑 x−yx-yx−y 路径如果要覆 ...

  9. 【Luogu】 P3242 [HNOI2015] 接水果

    题目链接 点击打开链接 题目解法 我们发现一段路径包含另一条不好做,但是被包含的关系就比较简单 对于每个盘子,我们可以分成 2 类情况,这里可以预处理出dfn序,令st[u]为进入u的时间,ed[u] ...

  10. BZOJ 4009 HNOI2015 接水果 树套树

    题目大意:给定一棵树和m<script type="math/tex" id="MathJax-Element-32">m</script&g ...

最新文章

  1. 了解过去与理解现在的一把钥匙
  2. shell脚本中获取当前所在目录地址
  3. 以太坊区块和交易存储
  4. 一种形式的两个提交按钮
  5. 【完结】12篇文章带你逛遍主流分割网络
  6. 打印tensorflow恢复模型中所有变量与操作节点
  7. 最大化_基于最大化互信息的学习目标
  8. 史陶比尔与机器人之父
  9. lucene api
  10. python selenium_自动化测试:Selenium+Python环境搭建
  11. VMware + Ubuntu16.04 网络无法使用问题
  12. 关于空间风靡的心理入侵小游戏浅析
  13. matlab自动运行,在指定时间自动运行Matlab程序
  14. 提高共射放大电路增益不改变直流偏置的手段
  15. 临时记录一次ic卡破解(1)
  16. 极客日报:爆字节跳动日均进账10.07亿元;iPhone 13粉屏上热搜;英特尔跌落神坛,CEO回应:是我们骄傲自大了
  17. 阿里linux内核月报201412
  18. Android8.0 蓝牙系统
  19. 三分钟带你学会修改VS的默认对齐数
  20. expected declaration or statement at end of input

热门文章

  1. Redis 基本数据类型
  2. Immutable 操作在 React 中的实践
  3. 《测试类职位面试360度》
  4. maven私服Nexus3.2的使用
  5. urllib urllib2 自己用
  6. python 报错 wxPyDeprecationWarning: Using deprecated class PySimpleApp.
  7. Linux rpm 命令参数详解
  8. [转载]ASP.NET MVC URL重写与优化(进阶篇)-继承RouteBase玩转URL
  9. Android应用--简、美音乐播放器增加音量控制
  10. 【Gbase】建表时候hash分布列的制定方式(DISTRIBUTED BY column_name)