●洛谷P3242 [HNOI2015]接水果
题链:
https://www.luogu.org/problemnew/show/P3242
题解:
整体二分,扫描线+树状数组。
详细的题解:http://blog.csdn.net/thy_asdf/article/details/50363672
得到各个盘子影响的矩形区域后,
那么我们就是要对每个询问代表的点查询覆盖了它的权值第k小的的那个矩形。
首先有一个简化版的问题,
就是查询改点被覆盖了多少次。可以用扫描线+树状数组做。
然后对于现在询问的第k小权值,
我们就可以二分答案,即二分一个权值mid,
然后判断是否这些权值小于mid的矩形可以覆盖该点至少k次,
使得话,缩小r,否则扩大l范围。
由于有多个询问,且分别做二分的话过程是一样的,所以可以整体二分。
另外,还可以对当前扫描线上的东西建立树套树,
外面是权值线段树,里面套的是区间线段树(方便区间修改,单点查询),也可以求出第k小的权值。
如果想看具体实现的话,推荐服用这位博主的代码:http://blog.csdn.net/make_it_for_good/article/details/52985365
再另外,好像还可以树上莫队+平衡树做,但是我太弱了,忘了树上莫队,就没写了。
但是我感觉如果用莫队的话,如果数据故意把水果和盘子的左端点放到同一个位置附近,
同时程序的分块又恰好把这些位置分在了同一个块,
可能会被卡成n^2的。
代码:
#include<bits/stdc++.h>
#define MAXN 160008
#define rint register int
using namespace std;
int N,P,Q,snt;
int ANS[MAXN],fa[MAXN][18],deep[MAXN],be[MAXN],en[MAXN];
struct Edge{
int ent;
int to[MAXN],nxt[MAXN],head[MAXN];
Edge(){ent=2;}
void Adde(int u,int v){
to[ent]=v; nxt[ent]=head[u]; head[u]=ent++;
}
}E;
struct Plate{
int x1,x2,y1,y2,val;
}S[MAXN];
struct info{
int x,yl,yr,val,id;
}A[MAXN],T[MAXN];
bool cmp1(const Plate &_A,const Plate &_B){
return _A.val<_B.val;
}
bool cmp2(const info &_A,const info &_B){
return _A.x<_B.x||(_A.x==_B.x&&_A.id<_B.id);
}
struct BIT{
int val[MAXN],n;
void Reset(int _n){n=_n;}
int Lowbit(int x){return x&(-x);}
void Modify(int l,int r,int x){//区间修改
if(l>r) return;
for(rint i=l;i<=n;i+=Lowbit(i)) val[i]+=x;
for(rint i=r+1;i<=n;i+=Lowbit(i)) val[i]-=x;
}
int Query(int p,int ret=0){//查询覆盖次数
for(rint i=p;i>=1;i-=Lowbit(i)) ret+=val[i];
return ret;
}
}DT;
void dfs(int u,int dad){
static int cnt; ++cnt;
be[u]=cnt; fa[u][0]=dad;
for(int k=1;k<18;k++)
fa[u][k]=fa[fa[u][k-1]][k-1];
for(int e=E.head[u];e;e=E.nxt[e]){
int v=E.to[e]; if(v==dad) continue;
deep[v]=deep[u]+1; dfs(v,u);
}
en[u]=cnt;
}
int jump(int x,int h){
for(int k=17;k>=0;k--)
if(h>=(1<<k)) x=fa[x][k],h-=(1<<k);
return x;
}
info inssegment(const Plate &rtm,int k){
static int x1,x2,y1,y2,v;
x1=rtm.x1; x2=rtm.x2; y1=rtm.y1; y2=rtm.y2; v=rtm.val;
assert(x1<=x2);
if(k==1) return (info){x1,y1,y2,v,-1};
else return (info){x2+1,y1,y2,v,-2};
}
void solve(int sl,int sr,int ql,int qr){
static int sum[MAXN];
if(ql>qr) return;
if(sl==sr){
for(int i=ql;i<=qr;i++) ANS[A[i].id]=S[sl].val;
return;
}
int mid=(sl+sr)>>1,tnt=0,qlnt=ql-1,qrnt=0;
for(int i=sl;i<=mid;i++) T[++tnt]=inssegment(S[i],1),T[++tnt]=inssegment(S[i],2);
for(int i=ql;i<=qr;i++) T[++tnt]=A[i];
sort(T+1,T+tnt+1,cmp2);
for(int i=1;i<=tnt;i++){
if(T[i].id<0) DT.Modify(T[i].yl,T[i].yr,T[i].id==-1?1:-1);
else sum[T[i].id]=DT.Query(T[i].yl);
}
for(int i=1;i<=tnt;i++){
if(T[i].id<0) DT.Modify(T[i].yl,T[i].yr,T[i].id==-1?-1:1);
else{
if(sum[T[i].id]>=T[i].val) A[++qlnt]=T[i];
else T[i].val-=sum[T[i].id],T[++qrnt]=T[i];
}
}
for(int i=1;i<=qrnt;i++) A[i+qlnt]=T[i];
solve(sl,mid,ql,qlnt);
solve(mid+1,sr,qlnt+1,qr);
}
int main(){
ios::sync_with_stdio(0);
cin>>N>>P>>Q;
for(int i=1,a,b;i<N;i++)
cin>>a>>b,E.Adde(a,b),E.Adde(b,a);
dfs(1,0); DT.Reset(N);
for(int i=1,x,y,v,t;i<=P;i++){
cin>>x>>y>>v;
if(be[x]>be[y]) swap(x,y);
if(be[x]<=be[y]&&en[x]>=en[y]){
t=jump(y,deep[y]-deep[x]-1);
S[++snt]=(Plate){1,be[t]-1,be[y],en[y],v};
if(en[t]+1<=N) S[++snt]=(Plate){be[y],en[y],en[t]+1,N,v};
}
else S[++snt]=(Plate){be[x],en[x],be[y],en[y],v};
}
sort(S+1,S+snt+1,cmp1);
for(int i=1,x,y,k;i<=Q;i++){
cin>>x>>y>>k;
if(be[x]>be[y]) swap(x,y);
A[i]=(info){be[x],be[y],0,k,i};
//在构建的二维平面里,x点对应的下标不是x,而是be[x]
//wa了一次,就是因为上面的那行代码写成了:
//A[i]=(info){x,y,0,k,i};
}
solve(1,snt,1,Q);
for(int i=1;i<=Q;i++) cout<<ANS[i]<<endl;
return 0;
}
●洛谷P3242 [HNOI2015]接水果的更多相关文章
- 洛谷 P3242 [HNOI2015]接水果 解题报告
P3242 [HNOI2015]接水果 题目描述 风见幽香非常喜欢玩一个叫做 \(osu!\) 的游戏,其中她最喜欢玩的模式就是接水果.由于她已经\(DT\) \(FC\) 了\(\tt{The\ b ...
- [洛谷P3242] [HNOI2015]接水果
洛谷题目链接:[HNOI2015]接水果 题目描述 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, 她觉得这个游戏太简 ...
- 洛谷P3242 接水果 [HNOI2015] 整体二分
正解:整体二分+树状数组 解题报告: 传送门! 题目还是大概解释下?虽然其实是看得懂的来着,,, 大概就是说给一棵树.给定一些询问,每个询问都是说在两个点之间的路径上的子路径的第k大是什么 然后看到这 ...
- 洛谷P3242 接水果
关于矩形与点其实有两种关系. 一种是每个矩形包含多少点.一种是每个点被多少矩形包含. 解:因为可以离线所以直接套整体二分.关键是考虑如何能够被覆盖. 我一开始都是想的树上操作...其实是转化成DFS序 ...
- [洛谷 P3239] [HNOI2015]亚瑟王
[HNOI2015]亚瑟王 题目描述 小 K 不慎被 LL 邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑.他决定,在脱坑之前,最后再来打一盘亚瑟王.既然是最后一战,就一定要打得漂亮.众所周知, ...
- 洛谷 P3241 [HNOI2015]开店 解题报告
P3241 [HNOI2015]开店 题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱. 这样的想法当然非 ...
- 洛谷P3244 [HNOI2015]落忆枫音
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #in ...
- luogu P3242 [HNOI2015]接水果
传送门 其实这题难点在于处理路径包含关系 先求出树的dfn序,现在假设路径\(xy\)包含\(uv(dfn_x<dfn_y,dfn_u<dfn_v)\) 如果\(lca(u,v)!=u\) ...
- 洛谷P3243 [HNOI2015]菜肴制作 拓扑排序+贪心
正解:拓扑排序 解题报告: 传送门! 首先看到它这个约束就应该要想到拓扑排序辣QwQ 首先想到的应该是用优先队列代替队列,按照节点编号排序 然后也很容易被hack:<5,1> 正解应为5, ...
随机推荐
- Beta 集合
Beta冲刺序列: Beta凡事预则立 :Beta No.0 Beta冲刺Day1:Beta No.1 Beta冲刺Day2:Beta No.2 Beta冲刺Day3:Beta No.3 Beta冲刺 ...
- 201621123060《JAVA程序设计》第一周学习总结
1.本周学习总结 1.讲述了JAVA的发展史,关于JDK.JRE.JVM的联系和区别 2.JDK是用JAVA开发工具.做项目的关键.JRE是JAVA的运行环境(JAVA也是JAVA语言开发的).JVM ...
- 使用Putty连接Amazon EC2 Instance
Amazon的EC2中,默认是不允许使用用户名和密码直接连接Instance的,而是通过AWS (Amazon Web Service)提供的证书.在第一次使用EC2的时候,AWS会要求你创建一个证书 ...
- 【iOS】swift 让程序挂起后,能在后台继续运行任务
1,程序的挂起和退出 由于iOS设备资源有限.当用户点击了home键,或者另一个应用程序启动了.那么原先那个程序便进入后台被挂起,不是退出,只是停止执行代码,同时它的内存被锁定.当应用程序恢复时,它会 ...
- day-2 如何搭建一个github代码库
最近在听尤瓦尔·赫拉利代写的两本书<人类简史>和<未来简史>两本书评,一部描述人类从哪里来,一部描述人类将往哪里去,书中阐述以前我们经历的饥饿.疾病和战争已经渐渐逝去,未来我们 ...
- Mego开发文档 - 数据注释建模
数据注释建模 Mego框架使用一组约定来基于CLR类来构建模型.您可以指定其他配置来补充或覆盖通过约定发现的内容. 在 Mego 中所有的数据对象必须要有主键.这里需要声明与EF不同的是框架只支持数据 ...
- 如何深入系统的学习一门编程语言——python自学笔记
前言 最早接触python的时候,他并没有现在这么火,我也没把他太当回事,那时候我对python的印象就是给运维人员使用的一门很古老的语言,显然随着tensorflow(以下简称tf)的兴起,pyth ...
- 浅谈Web网站的架构演变过程
前言 我们以javaweb为例,来搭建一个简单的电商系统,看看这个系统可以如何一步步演变. 该系统具备的功能: 用户模块:用户注册和管理 商品模块:商品展示和管理 交易模块:创建交易和管理 阶 ...
- python JavaScript
JavaScript 一. JavaScript Javascript 在开发中绝大多数情况是基于对象的.也是面向对象的. a. JavaScript的引入方式 1 2 3 4 5 6 7 #直接编写 ...
- python基础——生成器表达式
生成器表达式 1 生成器表达式定义 生成器表达式并不真正的创建数字列表,而是返回一个生成器对象,此对象在每次计算出一个条目后,把这个条目"产生"(yield)出来.生成器表达式使用 ...