http://www.lydsy.com/JudgeOnline/problem.php?id=4009 (题目链接)

题意

  给出一颗无根树。有一些路径记为$P_i$,这些路径有两个端点和一个权值$W_i$。另外一些路径记为$Q_i$,同样有两个端点和一个权值$K_i$。对于每个$Q_i$,询问$P$中路径是它的路径的子集的第$K_i$大的权值。

Solution

  整体二分很明显。怎么维护信息呢。右转题解:http://blog.csdn.net/thy_asdf/article/details/50363672

  所以线段树扫描线一搞就可以了。

细节

  不知不觉4KB了,可啪

代码

// bzoj4009
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf (1ll<<30)
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=40010;
int deep[maxn],in[maxn],out[maxn],head[maxn],fa[maxn][30],bin[30];
int vis[maxn],ans[maxn],sum[maxn],a[maxn];
int n,m,P,Q,dfn,cnt;
struct edge {int to,next;}e[maxn<<1];
struct node {int l,r,s,tag;}tr[maxn<<2];
struct event {int x,l,r,w,id,op;}p[maxn<<2],q[maxn],ql[maxn],qr[maxn]; namespace Segtree {
void build(int k,int s,int t) {
tr[k].l=s,tr[k].r=t;
if (s==t) return;
int mid=(s+t)>>1;
build(k<<1,s,mid);build(k<<1|1,mid+1,t);
}
void pushdown(int k) {
tr[k<<1].s+=tr[k].tag;tr[k<<1|1].s+=tr[k].tag;
tr[k<<1].tag+=tr[k].tag;tr[k<<1|1].tag+=tr[k].tag;
tr[k].tag=0;
}
void add(int k,int s,int t,int val) {
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
if (s==l && t==r) {tr[k].s+=val,tr[k].tag+=val;return;}
if (tr[k].tag) pushdown(k);
if (t<=mid) add(k<<1,s,t,val);
else if (s>mid) add(k<<1|1,s,t,val);
else add(k<<1,s,mid,val),add(k<<1|1,mid+1,t,val);
tr[k].s=tr[k<<1].s+tr[k<<1|1].s;
}
int query(int k,int s,int t) {
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
if (s==l && t==r) return tr[k].s;
if (tr[k].tag) pushdown(k);
if (t<=mid) return query(k<<1,s,t);
else if (s>mid) return query(k<<1|1,s,t);
else return query(k<<1,s,mid)+query(k<<1|1,mid+1,t);
}
}
using namespace Segtree; namespace Prepare {
bool cmpw(event a,event b) {return a.w<b.w;}
bool cmpx(event a,event b) {return a.x==b.x ? a.op<b.op : a.x<b.x;}
void link(int u,int v) {
e[++cnt]=(edge){v,head[u]};head[u]=cnt;
e[++cnt]=(edge){u,head[v]};head[v]=cnt;
}
void dfs(int x) {
in[x]=++dfn;
for (int i=1;i<=20;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa[x][0]) {
deep[e[i].to]=deep[x]+1;
fa[e[i].to][0]=x;
dfs(e[i].to);
}
out[x]=dfn;
}
int lca(int x,int y) {
if (deep[x]<deep[y]) swap(x,y);
int t=deep[x]-deep[y];
for (int i=0;bin[i]<=t;i++) if (bin[i]&t) x=fa[x][i];
for (int i=20;i>=0;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return x==y ? x : fa[x][0];
}
}
using namespace Prepare; void solve(int al,int ar,int pl,int pr,int L,int R) {
if (pl>pr || L>R) return;
if (al==ar) {
for (int i=L;i<=R;i++) ans[q[i].id]=al;
return;
}
sort(p+pl,p+pr+1,cmpw);
int mid=(al+ar)>>1;
int x=pl,y=L,cl=0,cr=0,lim;
for (lim=pl;p[lim].w<=mid;lim++);lim--;
sort(p+pl,p+lim+1,cmpx);
while (x<=lim || y<=R) {
if (y>R || (x<=lim && cmpx(p[x],q[y]))) add(1,p[x].l,p[x].r,p[x].id),x++;
else {
a[q[y].id]=query(1,q[y].l,q[y].r);
if (q[y].w<=sum[q[y].id]+a[q[y].id]) ql[++cl]=q[y];
else qr[++cr]=q[y];
y++;
}
}
for (int i=1;i<=cl;i++) q[L+i-1]=ql[i];
for (int i=cr;i>=1;i--) q[R-cr+i]=qr[i];
solve(al,mid,pl,lim,L,cl+L-1);
for (int i=L;i<=R;i++) sum[q[i].id]+=a[q[i].id];
solve(mid+1,ar,lim+1,pr,R-cr+1,R);
}
int main() {
bin[0]=1;for (int i=1;i<=20;i++) bin[i]=bin[i-1]<<1;
scanf("%d%d%d",&n,&P,&Q);
for (int u,v,i=1;i<n;i++) {
scanf("%d%d",&u,&v);
link(u,v);
}
dfs(1);
int mx=-inf,mn=inf;
for (int u,v,w,i=1;i<=P;i++) {
scanf("%d%d%d",&u,&v,&w);
mx=max(mx,w);mn=min(mn,w);
if (in[u]>in[v]) swap(u,v);
int f=lca(u,v);
if (f!=u) {
p[++m]=(event){in[u],in[v],out[v],w,1,1};
p[++m]=(event){out[u],in[v],out[v],w,-1,3};
}
else {
int d=deep[v]-deep[u]-1;u=v;
for (int i=0;bin[i]<=d;i++) if (bin[i]&d) u=fa[u][i];
p[++m]=(event){1,in[v],out[v],w,1,1};
p[++m]=(event){in[u]-1,in[v],out[v],w,-1,3};
if (out[u]<n) {
p[++m]=(event){in[v],out[u]+1,n,w,1,1};
p[++m]=(event){out[v],out[u]+1,n,w,-1,3};
}
}
}
for (int u,v,w,i=1;i<=Q;i++) {
scanf("%d%d%d",&u,&v,&w);
if (in[u]>in[v]) swap(u,v);
q[i]=(event){in[u],in[v],in[v],w,i,2};
}
sort(q+1,q+1+Q,cmpx);
build(1,1,n);
solve(mn,mx,1,m,1,Q);
for (int i=1;i<=Q;i++) printf("%d\n",ans[i]);
return 0;
}

【bzoj4009】 HNOI2015—接水果的更多相关文章

  1. [BZOJ4009][HNOI2015]接水果(整体二分)

    [HNOI2015]接水果 时间限制:60s      空间限制:512MB 题目描述 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果. 由于她已经DT FC 了The b ...

  2. BZOJ4009: [HNOI2015]接水果

    4009: [HNOI2015]接水果 Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果. 由于她已经DT FC 了The big black,  她 ...

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

    传送门 整体二分好题. 考虑水果被盘子接住的条件. 不妨设水果表示的路径为(x1,y1)(x_1,y_1)(x1​,y1​),盘子表示的为(x2,y2)(x_2,y_2)(x2​,y2​) 不妨设df ...

  4. [bzoj4009] [HNOI2015]接水果 整体二分+扫描线+dfs序+树状数组

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

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

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

  6. bzoj4009 [HNOI2015]接水果 整体二分+扫描线+树状数组+dfs序

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4009 题解 考虑怎样的情况就会有一个链覆盖另一个链. 设被覆盖的链为 \(a - b\),覆盖 ...

  7. 【BZOJ4009】[HNOI2015]接水果 DFS序+整体二分+扫描线+树状数组

    [BZOJ4009][HNOI2015]接水果 Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, ...

  8. 【BZOJ4009】接水果(整体二分,扫描线)

    [BZOJ4009]接水果(整体二分,扫描线) 题面 为什么这都是权限题???,洛谷真良心 题解 看到这道题,感觉就是主席树/整体二分之类的东西 (因为要求第\(k\)大) 但是,读完题目之后,我们发 ...

  9. BZOJ 4009: [HNOI2015]接水果

    4009: [HNOI2015]接水果 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 636  Solved: 300[Submit][Status] ...

  10. 洛谷 P3242 [HNOI2015]接水果 解题报告

    P3242 [HNOI2015]接水果 题目描述 风见幽香非常喜欢玩一个叫做 \(osu!\) 的游戏,其中她最喜欢玩的模式就是接水果.由于她已经\(DT\) \(FC\) 了\(\tt{The\ b ...

随机推荐

  1. 20155232《网络对抗》Exp2 后门原理与实践

    20155232<网络对抗>Exp2 后门原理与实践 问题回答 1.例举你能想到的一个后门进入到你系统中的可能方式? 通过网页上弹出来的软件自动安装 2.例举你知道的后门如何启动起来(wi ...

  2. CLR回收非托管资源

    一.非托管资源 在<垃圾回收算法之引用计数算法>.<垃圾回收算法之引用跟踪算法>和<垃圾回收算法之引用跟踪算法>这3篇文章中,我们介绍了垃圾回收的一些基本概念和原理 ...

  3. MiZ702学习笔记11——如何使用vivado isim仿真

    说到vivado的仿真确实是很有意思,不管是ISE还是Quartus都可以自己自动生成测试平台的完整构架,但是vivado不行,所有的测试代码自己写!(我反正是查了好久,都没发现vivado如何自动生 ...

  4. 基于Boost库的HTTP Post函数

    两个函数的区别: 提交表单数据和提交文本数据 表单数据: request_stream << "Content-Type: application/x-www-form-urle ...

  5. JS基础内容小结(event 鼠标键盘事件)(三)

    var ev=ev||event 兼容性处理 得到焦点为 onfocus 失去焦点 onblur return false能阻止部分函数的执行 obj.select 选择指定元素里的文本内容 ———— ...

  6. 微信小程序初体验与DEMO分享

    前言 前一段时间微信公布小程序,瞬间引来了大量的关注.博主的公司也将其定为目标之一,遂派本菜为先头兵(踩坑侠). 这次开发了一个比较完整的DEMO,模仿自某个APP首页,由于保护隐私的目的我把数据拷贝 ...

  7. 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1

    摘要: 全球开源区块链领域影响最为广泛的Hyperledger Fabric日前宣布了1.1版本的正式发布,带来了一系列丰富的新功能以及在安全性.性能与扩展性等方面的显著提升.阿里云容器服务区块链解决 ...

  8. Codeforces Round #546 (Div. 2) E - Nastya Hasn't Written a Legend

    这题是一个贼搞人的线段树 线段树维护的是 区间和a[i - j] 首先对于update的位置可以二分查找 其次update时候的lazy比较技巧 比如更新的是 l-r段,增加的是c 那么这段的值为: ...

  9. html5实现拖拽上传头像

    1. 将客户端(本地电脑)中的图片拖到网页中 要点: html5 拖放, FileReader html: <div id="container" ondrop=" ...

  10. PAT甲题题解1099. Build A Binary Search Tree (30)-二叉树遍历

    题目就是给出一棵二叉搜索树,已知根节点为0,并且给出一个序列要插入到这课二叉树中,求这棵二叉树层次遍历后的序列. 用结构体建立节点,val表示该节点存储的值,left指向左孩子,right指向右孩子. ...