2811: [Apio2012]Guard

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 905  Solved: 387
[Submit][Status][Discuss]

Description


Input


Output


Sample Input

5 3 4
1 2 1
3 4 1
4 4 0
4 5 1

Sample Output

3
5

HINT

在这个样例中,有两种可能的安排方式:1,3,5 或者 2,3,5。即 3 和 5
后面必然躲着一个忍者。
考虑第一个灌木丛,存在一种安排方案使得它的后面躲着忍者,但也存在一
种安排方案使得它后面没有躲忍者,因此不应该输出 1。同理,不应该输出 2。

贪心。
把所有不可能出现忍者的位置除去,重新编号序列  可以用差分实现
对区间进行操作,对于可能存在忍者的区间,把它缩小到没有不可能出现忍者的位置,并去除包含关系
这样,剩下的区间就只能是l递增,r递增的了
对于每个剩下的区间,我们都要选一个区间内的点,根据贪心来说,选右端点最优
因为在几个区间重复的部分选一点可以使这几个区间都被处理,右端点最可能被几个区间包含

因此我们得到贪心策略:
对于每一个有效区间,选择右端点可以使满足每个区间的要求(当然有些区间包含之前选择的右端点就不选了),并让已知位置的忍者数最少

但是每个区间我们不一定要选择r点,还可能选择r-1,r-2,r-3...这些点来使得区间满足
现在我们要判断的是对于某一个区间,我们是否能唯一选择r点必定出现忍者

我们假设在r-1放一个忍者来满足当前区间且在r不放忍者,如果确实可以满足那么r点不一定会出现忍者
预处理出f[i],g[i]表示从前向后,从后向前选择点使得 到i的前缀,后缀区间都满足
设r-1不能满足的向前数第一个区间为t1,向后数第一个区间为t2   那么r-1不可行的条件就是f[t1]+g[t2]+1>K

至于为什么要选择r-1来判断r可行, 是因为r-1更有可能被更多的区间包含,让r不一定出现忍者的期望更大

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define ll long long
#define N 100050
using namespace std;
int n,m,k,cnt,val[N],f[N],g[N],cf[N],ql[N],qr[N];
struct query{int l,r,c;}q[N];
vector<pair<int,int> >p;
int main(){
scanf("%d%d%d",&n,&k,&m); //重新构造序列
for(int i=1;i<=m;i++){
scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].c);
if(!q[i].c)cf[q[i].l]++,cf[q[i].r+1]--;
}
int now=0;
for(int i=1;i<=n;i++){
now+=cf[i];
if(now<=0)ql[i]=qr[i]=++cnt,val[cnt]=i;
}
if(cnt==k){
for(int i=1;i<=cnt;i++)printf("%d\n",val[i]);
return 0;
}
for(int i=1;i<=n;i++)if(!qr[i])qr[i]=qr[i-1];
ql[n+1]=n+1;
for(int i=n;i;i--)if(!ql[i])ql[i]=ql[i+1];
for(int i=1;i<=m;i++){
if(!q[i].c)continue;
int l=q[i].l,r=q[i].r;
l=ql[l];r=qr[r];
if(l>r)continue;
p.push_back(make_pair(l,r));
}
sort(p.begin(),p.end());
int tp=0,fg=0;
for(int i=0;i<p.size();i++){
while(tp&&p[i].first>=ql[tp]&&p[i].second<=qr[tp])tp--;
ql[++tp]=p[i].first;qr[tp]=p[i].second;
}
//重新构造序列 int R=0,L=n+1;
for(int i=1;i<=tp;i++){
if(ql[i]>R)f[i]=f[i-1]+1,R=qr[i];
else f[i]=f[i-1];
}
for(int i=tp;i;i--){
if(qr[i]<L)g[i]=g[i+1]+1,L=ql[i];
else g[i]=g[i+1];
}
for(int i=1;i<=tp;i++){
if(f[i]==f[i-1])continue;
if(ql[i]==qr[i]){
printf("%d\n",val[ql[i]]);
fg=1;continue;
}
int x=qr[i]-1,l=1,r=i-1,t1=0,t2=tp+1;
while(l<=r){
int mid=l+r>>1;
if(qr[mid]<x)t1=mid,l=mid+1;
else r=mid-1;
}
l=i+1;r=tp;
while(l<=r){
int mid=l+r>>1;
if(ql[mid]>x)t2=mid,r=mid-1;
else l=mid+1;
}
if(f[t1]+g[t2]+1>k){
printf("%d\n",val[qr[i]]);
fg=1;
}
}
if(!fg)puts("-1");
return 0;
}

bzoj2811[Apio2012]Guard 贪心的更多相关文章

  1. bzoj2811 [Apio2012]Guard

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2811 [题解] 首先我们先把没看到忍者的段去掉,可以用线段树做. 如果剩下的就是K,那么特判 ...

  2. bzoj 2811: [Apio2012]Guard【线段树+贪心】

    关于没有忍者的区间用线段树判就好啦 然后把剩下的区间改一改:l/r数组表示最左/最右没被删的点,然后删掉修改后的左边大于右边的:l升r降排个序,把包含完整区间的区间删掉: 然后设f/g数组表示i前/后 ...

  3. 【bzoj2809】[Apio2012]dispatching 贪心+可并堆

    题目描述 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 Master以外,每名忍者都有且仅有一个上级.为保密,同时增 ...

  4. [BZOJ2809][Apio2012]dispatching 贪心+可并堆

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2809 我们考虑以每一个节点作为管理者所得的最优答案,一定是优先选择所要薪水少的忍者.那么首 ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. Bzoj 3126[Usaco2013 Open]Photo 题解

    3126: [Usaco2013 Open]Photo Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 335  Solved: 169[Submit] ...

  7. [差分][二分][贪心]luogu P3634 [APIO2012]守卫

    题面 https://www.luogu.com.cn/problem/P3634 给m个限制,可以是一段区间中必须有或者必须无忍者 最多有k个忍者,问有多少个位点一定有忍者 分析 首先用差分标记一下 ...

  8. C、Guard the empire(贪心)

    链接:https://ac.nowcoder.com/acm/contest/3570/C 来源:牛客网 题目描述 Hbb is a general and respected by the enti ...

  9. luogu P1552 [APIO2012]派遣 题解--可并堆/贪心

    题目链接: https://www.luogu.org/problemnew/show/P1552 分析: 一开始愣是没看懂题,后面发现就是你要找一个树上点集使得各点权值之和小于\(M\),并且找一个 ...

随机推荐

  1. codevs 3981 动态最大子段和

    3981 动态最大子段和 http://codevs.cn/problem/3981/    题目等级 : 钻石 Diamond   题目描述 Description 题目还是简单一点好... 有n个 ...

  2. 成功案例分享:raid5两块硬盘掉线数据丢失恢复方法

    1. 故障描述    本案例是HP P2000的存储vmware exsi虚拟化平台,由RAID-5由10块lT硬盘组成,其中6号盘是热备盘,由于故障导致RAID-5磁盘阵列的两块盘掉线,表现为两块硬 ...

  3. react基础篇入门组件

    讲述一下React: 1.声明式设计-React采用声明范式,可以轻松描述应用 2.高效-React通过DOM模型,最大限度的减少dom的交互 3.灵活-React可以与已知的库或框架很好的配合 4. ...

  4. Xdebug的优点!php代码开发

    可以跟踪函数,知道那个函数出错,之前只是输出一点调试信息,只是哪一行错了,并且是白色 如果是死循环,debug会对死循环判断一百次的循环,并且会给出每一次循环的时间,内存,和函数名,位置.根据时间可以 ...

  5. jsMath对象

    Math对象: abs.用来求绝对值. ceil:用来向上取整. floor:用来向下取整. round:用来四舍五入取近似值. sqrt:用来开方. pow:括号内有2位参数.如pow(2,5)表示 ...

  6. c 语言常量

    1,整数常量 整数常量可以是十进制.八进制或十六进制的常量.前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制. 整数常量也可以带一个后缀,后缀是 U 和 L 的组合 ...

  7. 算法题丨Remove Element

    描述 Given an array and a value, remove all instances of that value in-place and return the new length ...

  8. spring boot 中active的profile会和标准配置合并吗

    如下图,两个profile配置文件,一个默认的(application.properties),一个是test的. 活跃配置为test. spring.profiles.active=test ste ...

  9. 简单搭建SpringMVC框架详解

    在公司待了两年,用的一直是Spring+SpringMVC+Hibernate框架,都是公司自己搭建好的,自己从来没有主动搭建过,闲来无聊,自己搭建试试.一下即我搭建的过程以及搭建所遇到的问题,有部分 ...

  10. JavaScript 重点笔记

    JavaScript 重点笔记 ## 数组 // 必须掌握 - arr.length:获取数组元素的长度 - arr.splice(起始位置,长度):从数组中添加或删除元素. - arr.indexO ...