4009: [HNOI2015]接水果

Description

风见幽香非常喜欢玩一个叫做 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 小的那个盘子,每个盘子可重复使用(没有使用次数

的上限:一个盘子接完一个水果后,后面还可继续接其他水果,只要它是水

果路径的子路径)。幽香认为这个游戏很难,你能轻松解决给她看吗?

Input

第一行三个数 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 小一定存在。

Output

对于每个果子,输出一行表示选择的盘子的权值。

Sample Input

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

Sample Output

442139372 
333042360 
442139372 
283254485 
283254485 
217394434 
217394434 
217394434 
217394434 
217394434

HINT

N,P,Q<=40000。

整体二分还挺好写的囧

考虑一条路径A被另一条路径B包含的条件是:
设A的两端点为x,y,B的两端点为u,v。

当x、y构成了祖先关系时,设y为祖先、z为x到y路径上倒数第二个点,则u和v有一个应在x的子树中,另一个不在z的子树中。

当x、y不构成祖先关系时,则u和v有一个应在x的子树中,另一个在y的子树中。

那么一个盘子就可以变成一个或两个矩形,一个果子就可以对应一个二维点。

然后可以整体二分,问题转化成计算有多少个矩形包含了一个二维点。

#include<cstdio>
#include<cctype>
#include<queue>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
const int BufferSize=<<;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
if(head==tail) {
int l=fread(buffer,,BufferSize,stdin);
tail=(head=buffer)+l;
}
return *head++;
}
inline int read() {
int x=,f=;char c=Getchar();
for(;!isdigit(c);c=Getchar()) if(c=='-') f=-;
for(;isdigit(c);c=Getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
int n,m,q,first[maxn],next[maxn<<],to[maxn<<],e;
void AddEdge(int u,int v) {
to[++e]=v;next[e]=first[u];first[u]=e;
to[++e]=u;next[e]=first[v];first[v]=e;
}
int st[maxn],en[maxn],dep[maxn],anc[maxn][],ToT;
void dfs(int x,int fa) {
anc[x][]=fa;rep(i,,) anc[x][i]=anc[anc[x][i-]][i-];
st[x]=++ToT;dep[x]=dep[fa]+;
ren if(to[i]!=fa) dfs(to[i],x);
en[x]=ToT;
}
int swim(int x,int k) {
rep(i,,) if(k>>i&) x=anc[x][i];
return x;
}
struct Plate {
int x,y,l,r,val;
bool operator < (const Plate& ths) const {return val<ths.val;}
}A[maxn<<];
struct Apple {int x,y,k,id;}B[maxn];
struct Sol1 {
int x,l,r,val;
bool operator < (const Sol1& ths) const {return x<ths.x;}
}T[maxn<<];
struct Sol2 {
int x,y,id;
bool operator < (const Sol2& ths) const {return x<ths.x;}
}C[maxn<<];
int Q[maxn],ans[maxn],now[maxn],cur[maxn],sumv[maxn],Tmp[maxn],clo;
int query(int x) {
int res=;
for(;x;x-=x&-x) if(cur[x]==clo) res+=sumv[x];
return res;
}
void add(int x,int v) {
for(;x<=n;x+=x&-x) {
if(cur[x]!=clo) cur[x]=clo,sumv[x]=v;
else sumv[x]+=v;
}
}
void solve(int l,int r,int h,int t) {
if(h>t) return;
if(l==r) {
rep(i,h,t) ans[B[Q[i]].id]=A[l].val;
return;
}
int mid=l+r>>,m1=,m2=;
rep(i,l,mid) if(A[i].l<=A[i].r) {
T[++m1]=(Sol1){A[i].x,A[i].l,A[i].r,};
T[++m1]=(Sol1){A[i].y+,A[i].l,A[i].r,-};
}
rep(i,h,t) {
C[++m2]=(Sol2){B[Q[i]].x,B[Q[i]].y,i};
C[++m2]=(Sol2){B[Q[i]].y,B[Q[i]].x,i};
now[i]=;
}
clo++;sort(T+,T+m1+);sort(C+,C+m2+);
int j=;
rep(i,,m2) {
while(j<=m1&&T[j].x<=C[i].x) add(T[j].l,T[j].val),add(T[j].r+,-T[j].val),j++;
now[C[i].id]+=query(C[i].y);
}
int L=h,R=t;
rep(i,h,t) {
if(now[i]>=B[Q[i]].k) Tmp[L++]=Q[i];
else B[Q[i]].k-=now[i],Tmp[R--]=Q[i];
}
rep(i,h,t) Q[i]=Tmp[i];
solve(l,mid,h,R);solve(mid+,r,R+,t);
}
int main() {
n=read();m=read();q=read();
rep(i,,n) AddEdge(read(),read());
dfs(,);int tmp=;
rep(i,,m) {
int x=read(),y=read(),v=read();
if(dep[x]<dep[y]) swap(x,y);
if(st[x]>=st[y]&&st[x]<=en[y]) {
y=swim(x,dep[x]-dep[y]-);
A[++tmp]=(Plate){st[x],en[x],,st[y]-,v};
A[++tmp]=(Plate){st[x],en[x],en[y]+,n,v};
}
else A[++tmp]=(Plate){st[x],en[x],st[y],en[y],v};
}
m=tmp;sort(A+,A+m+);
rep(i,,q) {
Q[i]=i;int x=read(),y=read(),val=read();
B[i]=(Apple){st[x],st[y],val,i};
}
solve(,m,,q);
rep(i,,q) printf("%d\n",ans[i]);
return ;
}

BZOJ4009: [HNOI2015]接水果的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  8. BZOJ 4009: [HNOI2015]接水果

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

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

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

随机推荐

  1. CI邮箱中SMTP的一些端口

    介绍其他几个常用邮箱设置,并以网易126邮箱为例,发图.        一.新浪邮箱(1)新浪邮箱自08年6月分服务器被攻击后开始对pop取件频率进行了严格**,同时新注册的用户需要手动才能开通pop ...

  2. object-c面向对象1

    ---恢复内容开始--- 类,对象,方法,属性. 类是object-c一种重要的数据类型,是组成object-c程序的基本要素.object-c的类声明和实现包括两个部分:接口和实现部分. @inte ...

  3. 2013 ACM/ICPC 长春网络赛F题

    题意:两个人轮流说数字,第一个人可以说区间[1~k]中的一个,之后每次每人都可以说一个比前一个人所说数字大一点的数字,相邻两次数字只差在区间[1~k].谁先>=N,谁输.问最后是第一个人赢还是第 ...

  4. 利用FFmpeg生成视频缩略图 2.3.1

    1.下载FFmpeg文件包,解压包里的\bin\下的文件解压到 D:\ffmpeg\ 目录下. 下载地址 http://ffmpeg.zeranoe.com/builds/win32/static/ ...

  5. Java for LeetCode 037 Sudoku Solver

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

  6. Java for LeetCode 032 Longest Valid Parentheses

    Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...

  7. Html标签<a>的target属性

    target属性规定了在何处打开超链接的文档. 如果在一个 <a> 标签内包含一个 target 属性,浏览器将会载入和显示用这个标签的 href 属性命名的.名称与这个目标吻合的框架或者 ...

  8. August 3rd, 2016, Week 32nd, Wednesday

    I am looking for someone to share in an adventure. 我在找能和我一起分享冒险之旅的人. We are all looking for someone ...

  9. CentOS 5.8/6.7若干优化

    CentOS系统安装之后并不能立即投入生产环境使用,往往需要先经过我们运维人员的优化才行.在此讲解几点关于Linux系统安装后的基础优化操作.注意:本次优化都是基于CentOS(5.8/6.7). 下 ...

  10. Wcf for wp8 使用iis Express 承载Wcf服务部署发布网站(三)

    我们接下来要做的是 本地电脑当作服务器(模拟外网服务器)来承载Wcf服务程序,通过引用本地电脑ip地址访问wcf服务程序接口 http://192.168.1.123/Service1.svc 一.先 ...