bzoj 2811: [Apio2012]Guard【线段树+贪心】
关于没有忍者的区间用线段树判就好啦
然后把剩下的区间改一改:l/r数组表示最左/最右没被删的点,然后删掉修改后的左边大于右边的;l升r降排个序,把包含完整区间的区间删掉;
然后设f/g数组表示i前/后的最少需要忍者数,这个贪心来转移即可,就是把忍者放在区间的最右/左位置
然后对于每个r判断。为什么是每个r而不是全部点,因为上一步的贪心。找到最右的r小于当前r-1的位置k1,最左的l大于当前r-1的位置k2,判断如果f[k1]+g[k2]+1>k,则说明此方案不合法,说明这个点必选
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=500005;
int n,k,m,tot,cnt,rl[N],l[N],r[N],con,f[N],g[N];
struct xds
{
int l,r,tg;
}t[N<<1];
struct qwe
{
int l,r,v;
qwe(int L=0,int R=0)
{
l=L,r=R;
}
}a[N],b[N];
bool cmp(const qwe &a,const qwe &b)
{
return a.l<b.l||(a.l==b.l&&a.r>b.r);
}
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
void build(int ro,int l,int r)
{
t[ro].l=l,t[ro].r=r;
if(l==r)
return;
int mid=(l+r)>>1;
build(ro<<1,l,mid);
build(ro<<1|1,mid+1,r);
}
void update(int ro,int l,int r)
{
if(t[ro].l==l&&t[ro].r==r)
{
t[ro].tg=1;
return;
}
int mid=(t[ro].l+t[ro].r)>>1;
if(r<=mid)
update(ro<<1,l,r);
else if(l>mid)
update(ro<<1|1,l,r);
else
{
update(ro<<1,l,mid);
update(ro<<1|1,mid+1,r);
}
}
int ques(int ro,int x)
{
if(t[ro].tg)
return t[ro].tg;
if(t[ro].l==t[ro].r)
return 0;
int mid=(t[ro].l+t[ro].r)>>1;
if(x<=mid)
return ques(ro<<1,x);
else
return ques(ro<<1|1,x);
}
int main()
{
n=read(),k=read(),m=read();
build(1,1,n);
for(int i=1;i<=m;i++)
{
int x=read(),y=read(),z=read();
if(!z)
update(1,x,y);
else
a[++tot]=qwe(x,y);
}
for(int i=1;i<=n;i++)
if(!ques(1,i))
l[i]=r[i]=++cnt,rl[cnt]=i;
if(cnt==k)
{
for(int i=1;i<=n;i++)
if(l[i])
printf("%d\n",i);
return 0;
}
for(int i=1;i<=n;i++)
if(!l[i])
l[i]=l[i-1];
r[n+1]=cnt+1;
for(int i=n;i>=1;i--)
if(!r[i])
r[i]=r[i+1];
for(int i=1;i<=tot;i++)
{
a[i].l=r[a[i].l],a[i].r=l[a[i].r];
if(a[i].l<=a[i].r)
a[++con]=a[i];
}
sort(a+1,a+1+con,cmp);
tot=0;
for(int i=1;i<=con;i++)
{
while(tot>=1&&b[tot].l<=a[i].l&&a[i].r<=b[tot].r)
tot--;
b[++tot]=a[i];
}
int mn=1e9,mx=0;
for(int i=1;i<=tot;i++)
{
if(b[i].l>mx)
f[i]=f[i-1]+1,mx=b[i].r;
else
f[i]=f[i-1];
}
for(int i=tot;i>=1;i--)
{
if(b[i].r<mn)
g[i]=g[i+1]+1,mn=b[i].l;
else
g[i]=g[i+1];
}
bool fl=0;
for(int i=1;i<=tot;i++)
{
if(f[i]!=f[i-1]+1)
continue;
if(b[i].l==b[i].r)
{
fl=1;
printf("%d\n",rl[b[i].l]);
continue;
}
int x=b[i].r-1,l=1,r=i-1,k1=0,k2=tot+1;
while(l<=r)
{
int mid=(l+r)>>1;
if(b[mid].r<x)
k1=mid,l=mid+1;
else
r=mid-1;
}
l=i+1,r=tot;
while(l<=r)
{
int mid=(l+r)>>1;
if(b[mid].l>x)
k2=mid,r=mid-1;
else
l=mid+1;
}
if(f[k1]+g[k2]+1>k)
fl=1,printf("%d\n",rl[b[i].r]);
}
if(!fl)
puts("-1");
return 0;
}
bzoj 2811: [Apio2012]Guard【线段树+贪心】的更多相关文章
- Bzoj5251 线段树+贪心
Bzoj5251 线段树+贪心 记录本蒟蒻省选后的第一篇题解!国际惯例的题面:首先这个东西显然是一棵树.如果我们把数值排序,并建立这棵树的dfs序,显然dfs序上的一个区间对应数值的一个区间,且根为数 ...
- BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心
BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心 Description 在计算机中,CPU只能和高速缓存Cache直接交换数据.当所需的内存单元不在Cache中时,则需要从主存里把数 ...
- 2018.10.20 NOIP模拟 蛋糕(线段树+贪心/lis)
传送门 听说是最长反链衍生出的对偶定理就能秒了. 本蒟蒻直接用线段树模拟维护的. 对于第一维排序. 维护第二维的偏序关系可以借助线段树/树状数组维护逆序对的思想建立权值线段树贪心求解. 代码
- Bzoj 2752 高速公路 (期望,线段树)
Bzoj 2752 高速公路 (期望,线段树) 题目链接 这道题显然求边,因为题目是一条链,所以直接采用把边编上号.看成序列即可 \(1\)与\(2\)号点的边连得是. 编号为\(1\)的点.查询的时 ...
- BZOJ2809&&LG1552 APIO2012派遣(线段树合并)
BZOJ2809&&LG1552 APIO2012派遣(线段树合并) 题面 自己找去 HINT 简化一题面就是让你从每个点的子树中以\(<=m\)的代价选取尽可能多的点,然后乘上 ...
- BZOJ 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle 线段树 + 贪心
escription 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i群牛一共有Mi(1&l ...
- codeforces 675E Trains and Statistic 线段树+贪心统计
分析:这个题刚看起来无从下手 但是我们可以先简化问题,首先可以固定起点i,求出i+1到n的最小距离 它可以到达的范围是[i+1,a[i]],贪心的想,我们希望换一次车可以到达的距离尽量远 即:找一个k ...
- BZOJ.3938.Robot(李超线段树)
BZOJ UOJ 以时间\(t\)为横坐标,位置\(p\)为纵坐标建坐标系,那每个机器人就是一条\(0\sim INF\)的折线. 用李超线段树维护最大最小值.对于折线分成若干条线段依次插入即可. 最 ...
- BZOJ.1558.[JSOI2009]等差数列(线段树 差分)
BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...
随机推荐
- vagrant的学习 之 Yii2
vagrant的学习 之 Yii2 本文根据慕课网的视频教程练习,感谢慕课网! 慕课视频学习地址:https://www.imooc.com/video/14218. 慕课的参考文档地址:https: ...
- ***iOS学习之Table View的简单使用和DEMO示例(共Plain普通+Grouped分组两种)
Table View简单描述: 在iPhone和其他iOS的很多程序中都会看到Table View的出现,除了一般的表格资料展示之外,设置的属性资料往往也用到Table View,Table View ...
- apc smart UPS下使用apcupsd注意事项
公司的apc smart UPS安装有管理卡(似乎是AP-9631),server环境有FreeBSD.Windows Server.Linux(CentOS.Ubuntu) 实际使用中有例如以下问题 ...
- ubuntu磁盘分区和挂载
- input 文本框禁止输入表情
js在用户输入表情时自动过滤掉 <input type="text" id="input" maxlength="10"/> v ...
- Lucene中TokenStream,Tokenizer,TokenFilter,TokenStreamComponents与Analyzer
TokenStream extends AttributeSource implements Closeable: incrementToken,end,reset,close Tokenizer直接 ...
- IEnumerator<TItem>和IEnumerator Java 抽象类和普通类、接口的区别——看完你就顿悟了
IEnumerable 其原型至少可以说有15年历史,或者更长,它是通过 IEnumerator 来定义的,而后者中使用装箱的 object 方式来定义,也就是弱类型的.弱类型不但会有性能问题,最主要 ...
- Opengl ES 1.x NDK实例开发之七:旋转的纹理立方体
开发框架介绍请參见:Opengl ES NDK实例开发之中的一个:搭建开发框架 本章在第六章(Opengl ES 1.x NDK实例开发之六:纹理贴图)的基础上绘制一个旋转的纹理立方体,原理和纹理贴图 ...
- 算法导论—无向图的遍历(BFS+DFS,MATLAB)
华电北风吹 天津大学认知计算与应用重点实验室 最后改动日期:2015/8/22 无向图的存储方式有邻接矩阵,邻接链表,稀疏矩阵等. 无向图主要包括双方面内容,图的遍历和寻找联通分量. 一.无向图的遍历 ...
- ASP.NET MVC中为DropDownListFor设置选中项的方法
在MVC中,当涉及到强类型编辑页,如果有select元素,需要根据当前Model的某个属性值,让Select的某项选中.本篇只整理思路,不涉及完整代码. □ 思路 往前台视图传的类型是List< ...