传送门: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. ubuntu开启crontab日志

    今天发现Ubuntu的/var/log下没有cron日志,用下面的命令即可开启: -default.conf cron.*              /var/log/cron.log #将cron前 ...

  2. LeetCode 全解(bug free 训练)

    1.Two Sum Given an array of integers, return indices of the two numbers such that they add up to a s ...

  3. 九度OJ--Q1168

    import java.util.Scanner; public class q1168 { public static void main(String[] args) { Scanner scan ...

  4. 机器学习 (一) 单变量线性回归 Linear Regression with One Variable

    文章内容均来自斯坦福大学的Andrew Ng教授讲解的Machine Learning课程,本文是针对该课程的个人学习笔记,如有疏漏,请以原课程所讲述内容为准.感谢博主Rachel Zhang的个人笔 ...

  5. DM8168通过GPMC接口与FPGA高速数据通信实现

    硬件:TI达芬奇TMS320DM8168(以下简称DSP).EP4CE6E22C8N(以下简称FPGA) 软件:linux-2.6.37 转载请注明出处- http://www.cnblogs.com ...

  6. Go基础篇【第8篇】: 内置库模块 bytes [二]

    type Reader ¶ type Reader struct { // 内含隐藏或非导出字段 } Reader类型通过从一个[]byte读取数据,实现了io.Reader.io.Seeker.io ...

  7. 使用IMAGEMAGICK的CONVERT工具批量转换图片格式

    使用IMAGEMAGICK的CONVERT工具批量转换图片格式 http://www.qiansw.com/linux-imagemagick-convert-img.html Home > 文 ...

  8. 剑指offer:斐波那契数列

    目录 题目 解题思路 具体代码 题目 题目链接 剑指offer:斐波那契数列 题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). n< ...

  9. webstorm-前端javascript开发神器中文教程和技巧分享(转)

    webstorm是一款前端javascript开发编辑的神器,此文介绍webstorm的中文教程和技巧分享. webstorm8.0.3中文汉化版下载: 百度网盘下载:http://pan.baidu ...

  10. PokeCats开发者日志(四)

      现在是PokeCats游戏开发的第八天的上午,感觉游戏做得差不多了,来写一下开发者日志吧!   (1)增加闯关模式,一共30关.   (2)更改了最后一关的主题,更换了背景,将树桩改为礼物盒.   ...