传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2811

【题解】

首先我们先把没看到忍者的段去掉,可以用线段树做。

如果剩下的就是K,那么特判即可。

我们可以把包含关系去掉然后对于剩下的区间,x单增,y单增。

否则的话,我们有一个结论(挺显然的):只有每个区间的右段点才能成为答案。

我们贪心地填肯定是填右端点。

所以我们判断如果右端点填到了前一个位置是否可行即可,如果不可行那么必须填右端点。

二分出这个位置所覆盖的区间(我们钦定填了这里)

然后我们维护fp[i]表示左边i个区间最少填多少,fs[i]表示右边i个区间最少填多少(前缀、后缀)

然后我们判断fp[l]+fs[r]+1是否大于K即可,如果大于,说明一定要填。

# include <stdio.h>
# include <string.h>
# include <algorithm>
// # include <bits/stdc++.h> using namespace std; typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + ;
const int mod = 1e9+; # define RG register
# define ST static int n, K, m; int x[M];
struct guard {
int l, r;
guard() {}
guard(int l, int r) : l(l), r(r) {}
friend bool operator < (guard a, guard b) {
return a.l < b.l || (a.l == b.l && a.r > b.r);
}
}a[M], o[M]; int on; bool del[M];
int new_id[M], idx, old_id[M];
int pre[M], nxt[M];
int fp[M], fs[M]; namespace SMT {
int w[M];
# define ls (x<<)
# define rs (x<<|)
inline void edt(int x, int l, int r, int L, int R) {
if(w[x]) return;
if(L <= l && r <= R) {
w[x] = ;
return ;
}
int mid = l+r>>;
if(L <= mid) edt(ls, l, mid, L, R);
if(R > mid) edt(rs, mid+, r, L, R);
}
inline int query(int x, int l, int r, int pos) {
if(w[x]) return ;
if(l == r) return ;
int mid = l+r>>;
if(pos <= mid) return query(ls, l, mid, pos);
else return query(rs, mid+, r, pos);
}
# undef ls
# undef rs
} int main() {
scanf("%d%d%d", &n, &K, &m);
for (int i=; i<=m; ++i) scanf("%d%d%d", &a[i].l, &a[i].r, x+i);
for (int i=; i<=m; ++i) if(x[i] == ) SMT::edt(, , n, a[i].l, a[i].r);
for (int i=; i<=n; ++i) {
if(SMT::query(, , n, i) == ) {
new_id[i] = ++idx, old_id[idx] = i;
// printf("i = %d, idx = %d\n", i, idx);
}
else del[i] = ;
}
if(idx == K) {
for (int i=; i<=n; ++i)
if(!del[i]) printf("%d\n", i);
return ;
}
for (int i=; i<=n; ++i) {
if(!del[i]) pre[i] = i;
else pre[i] = pre[i-];
}
for (int i=n; i; --i) {
if(!del[i]) nxt[i] = i;
else nxt[i] = nxt[i+];
}
for (int i=; i<=m; ++i) {
int nl = nxt[a[i].l], nr = pre[a[i].r];
if(nl <= nr) o[++on] = guard(new_id[nl], new_id[nr]);
}
sort(o+, o+on+);
m = ;
for (int i=; i<=on; ++i) {
while(m && o[i].l >= a[m].l && o[i].r <= a[m].r) --m;
a[++m] = o[i];
}
// for (int i=1; i<=m; ++i)
// printf("%d %d\n", a[i].l, a[i].r);
int cur = ;
for (int i=; i<=m; ++i)
if(a[i].l > cur) fp[i] = fp[i-] + , cur = a[i].r;
else fp[i] = fp[i-];
cur = 1e9;
for (int i=m; i; --i)
if(a[i].r < cur) fs[i] = fs[i+] + , cur = a[i].l;
else fs[i] = fs[i+]; bool have_ans = ; for (int i=, x, l, r, ans1, ans2; i<=m; ++i) {
if(fp[i] != fp[i-]+) continue;
if(a[i].l == a[i].r) {
have_ans = ;
// printf("=%d\n", a[i].r);
printf("%d\n", old_id[a[i].r]);
continue;
}
// 考察每个区间的右端点是否可行
x = a[i].r-;
l = , r = i-, ans1 = ;
while() {
if(r-l<=) {
for (int j=r; j>=l; --j)
if(a[j].r < x) {
ans1 = j;
break;
}
break;
}
int mid = l+r>>;
if(a[mid].r < x) l = mid;
else r = mid;
}
l = i+, r = m, ans2 = m+;
while() {
if(r-l<=) {
for (int j=l; j<=r; ++j)
if(a[j].l > x) {
ans2 = j;
break;
}
break;
}
int mid = l+r>>;
if(a[mid].l > x) r = mid;
else l = mid;
}
// printf("%d %d\n", ans1, ans2);
if(fp[ans1] + fs[ans2] + > K) {
// printf("=%d\n", a[i].r);
printf("%d\n", old_id[a[i].r]);
have_ans = ;
}
} if(!have_ans) puts("-1"); return ;
}

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

  1. bzoj2811[Apio2012]Guard 贪心

    2811: [Apio2012]Guard Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 905  Solved: 387[Submit][Statu ...

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

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

  3. bzoj AC倒序

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

  4. Bzoj 3126[Usaco2013 Open]Photo 题解

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

  5. swift中 if let 与 guard let 对比,guard会降低一个分支

    //用if let与guard let实现同一效果,会发现guard降低一个分支 //可以用if var guard var 表示定义的变量能修改值 func test(){ let name:Str ...

  6. CentOS 安装 Zend Guard Loader

    说明:PHP5.3以上的版本不再支持Zend Optimizer,已经被全新的 Zend Guard Loader 取代,下面是安装Zend Guard具体步骤,以下操作均在终端命令行执行 在 Zen ...

  7. Oracle Data Guard的配置

    概述 Oracle Data Guard 是针对企业数据库的最有效和最全面的数据可用性.数据保护和灾难恢复解决方案.它提供管理.监视和自动化软件基础架构来创建和维护一个或多个同步备用数据库,从而保护数 ...

  8. PHP加速处理插件 Zend Optimizer,Zend Guard Loader 和 Zend Opcache 区别

    PHP 5.3.X   以前版本 为  Zend Optimizer PHP 5.3.X   之后 更名为  Zend Guard Loader 可以帮助php执行加密后的php代码 安装实例以Ubu ...

  9. 场景7 Data Guard

    场景7  Data Guard 官方文档 :Oracle Data Guard Concepts and Administration 用于数据容灾,通过主备库同步(主库将redo日志传送到备库,一个 ...

随机推荐

  1. stm32--FatFs调试过程(SPIFlash)

    移植方法参见我的另一篇博客:<stm32--FatFs移植(SPIFlash)>. 本文仅记录在初次移植完成后,遇到的问题,和解决的过程. 调试记录: 问题1:f_open返回3,即磁盘没 ...

  2. web框架与爬虫

    所有的web框架 http://www.cnblogs.com/wupeiqi/articles/5341480.html 爬虫技术 http://www.cnblogs.com/wupeiqi/ar ...

  3. MyEclipse - 问题集 - 创建Maven项目,JDK版本默认是1.5

    修改Maven的配置文件settings.xml,增加profile节点,如下所示: <profile> <id>jdk-1.8</id> <activati ...

  4. android中接入twitter进行第三方登录

    在应用中接入Twitter进行第三方登录时,开发人员遇到了一点问题,主要是概念有点混乱,这里把经验记录一下,帮助遇到同样问题的朋友. 一.注册应用并配置登录权限 这一步比较简单,就不多说了,直接去官网 ...

  5. shiro笔记

    控制某一角色拥有此选项 上图 标签为shiro:hasRole表示 此时只有admin角色才拥有 系统用户管理和角色管理两个tab 页 上图 标签为shiro:hasPermission表示 此时只有 ...

  6. python 基础篇 16 递归和二分数查找与编码补充回顾

    编码回顾补充: 回顾编码问题:        编码相当于密码本,关系到二进制与看懂的文字的的对应关系.    最早期的密码本:        ascii码:只包含英文字母,数字,特殊字符.       ...

  7. Spark集群管理器介绍

    Spark可以运行在各种集群管理器上,并通过集群管理器访问集群中的其他机器.Spark主要有三种集群管理器,如果只是想让spark运行起来,可以采用spark自带的独立集群管理器,采用独立部署的模式: ...

  8. 容器基础(十): 使用kubernetes部署应用

    概述 使用之前的脚本(env/server.py 得到 env/server:v0.1 镜像, env/worker.py 得到 env/worker:v0.1)得到的镜像,在部署好kubernete ...

  9. sqlserver 找出字符第N次出现的位置

    [1编写函数]CREATE FUNCTION IndexOf(@str VARCHAR(500),@value VARCHAR(50),@posIndex INT)RETURNS int AS BEG ...

  10. STL应用——hdu1412(set)

    set函数的应用 超级水题 #include <iostream> #include <cstdio> #include <algorithm> #include ...