传送门: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. 当我们访问不了虚拟机上ip上的web页面,是因为在window上要添加映射

    在主机上添加映射步骤 1.打开C盘 注意:用nopedata++打开 保存即可!

  2. ExtJs工具篇(2)——Aptana Studio 3 汉化

    本身用的是中文版本的,但是输入一些中文后,竟然有乱码,所以就想把它汉化.在网上搜索了一下,把步骤记录如下: 首先到这个网站去 http://aptana.com/support 选择View Docu ...

  3. Apache 配置说明

    ServerRoot ServerRoot: The top of the directory tree under which the server's configuration, error, ...

  4. 最火的.NET开源项目[转]

    综合类 微软企业库 微软官方出品,是为了协助开发商解决企业级应用开发过程中所面临的一系列共性的问题, 如安全(Security).日志(Logging).数据访问(Data Access).配置管理( ...

  5. 【java并发编程】十三章:显式锁:LOCK

    java5以后,新增了显式锁,用于当内置锁不能满足需求后可选择的一种高级方案. lock接口的特点 与内置锁一样,他能提供互斥性,内存可见性,可重入等特征,与内置锁不同的是,Lock提供了一种无条件, ...

  6. svn建立主干和分支在分支上开发然后合并到主干

    我们以后打算用svn分支了,如何避免对新事物的恐惧心理呢? 领导: “我们需要慢慢适应,开始的时候我们先用一个项目练手,等熟悉了之后,再把每个项目都建上分支”

  7. WebStorm强大的调试JavaScript功能(转载)

    一.JavaScript的调试 目前火狐和Chrome都具备调试JavaScript的功能,而且还是相当的强大.如果纯粹是用浏览器来进行js调试的话,我比较喜欢用火狐.火狐可以安装各种插件,真的是非常 ...

  8. 算法(11)Find All Duplicates in an Array

    题目:数组的长度是n,里面的数是1到n,其中肯定有重复的,找到里面重复的数字 思路:自己想愣是没有想出来,直接看答案,关键点是看nums[i]和nums[nums[i]-1]之间的关系,遍历整个数组, ...

  9. [剑指Offer] 3.从尾到头打印链表

    题目描述 输入一个链表,从尾到头打印链表每个节点的值. [思路]用一个vector存储,遍历链表时每次从前面插入 /** * struct ListNode { * int val; * struct ...

  10. ai学习记录

    界面:多个预编辑区:制作图形,使用的图形放到工作区内,不使用在预编区.没有Ctrl/Alt+delete的概念,没有前后景颜色.新建:分辨率:矢量软件和分辨率无关: 新建时候不要勾选对齐到像素网格 存 ...