题面

https://www.luogu.com.cn/problem/P3634

给m个限制,可以是一段区间中必须有或者必须无忍者

最多有k个忍者,问有多少个位点一定有忍者

分析

首先用差分标记一下0忍者的区间,去掉

然后再删去包含了其他区间的区间,没有意义

将剩余区间按左端点排序,方便处理

考虑计算处理到第i个区间所需的最少忍者数,如果该区间内没有已经被选择的点,贪心选择右端点使总点数最少

倒着处理一遍,类似,不过是贪心选择左端点

枚举每个右端点考虑不选择它而选择它的左侧端点,并二分找到不与它相交的最近的左右两个区间

若从左侧开始处理到左侧区间的最少忍者数+从右侧开始处理到右侧区间的最少忍者数+1(选择当前区间)的所需忍者数大于k,那么说明不选这个右端点是不合法的,所以这个点必选

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=1e5+10;
struct Guard {
int a,b,c;
}g[N];
int n,k,m,zm,gcnt;
int zer[N],ref[N],rcnt,nearl[N],nearr[N],f[N],h[N];
bool ans; bool CMP(Guard a,Guard b) {return a.a<b.a;} int main() {
scanf("%d%d%d",&n,&k,&m);
for (int i=1;i<=m;i++) {
scanf("%d%d%d",&g[i].a,&g[i].b,&g[i].c);
if (!g[i].c) zer[g[i].a]++,zer[g[i].b+1]--;
}
for (int i=1;i<=n;i++) {
zer[i]+=zer[i-1];
if (!zer[i]) ref[nearl[i]=nearr[i]=++rcnt]=i;
else nearl[i]=n+1;
}
if (rcnt==k) {for (int i=1;i<=rcnt;i++) printf("%d\n",ref[i]);return 0;}
for (int i=2;i<=n;i++) nearr[i]=max(nearr[i],nearr[i-1]),nearl[n-i+1]=min(nearl[n-i+1],nearl[n-i+2]);
for (int i=1;i<=m;i++) if (g[i].c&&nearl[g[i].a]<=nearr[g[i].b]) g[++zm].a=nearl[g[i].a],g[zm].b=nearr[g[i].b];
sort(g+1,g+zm+1,CMP);
for (int i=1;i<=zm;i++) {
while (gcnt&&g[gcnt].a<=g[i].a&&g[i].b<=g[gcnt].b) gcnt--;
g[++gcnt]=g[i];
}
for (int i=1,r=0;i<=gcnt;i++) if (g[i].a>r) f[i]=f[i-1]+1,r=g[i].b; else f[i]=f[i-1];
for (int i=gcnt,l=n+1;i;i--) if (g[i].b<l) h[i]=h[i+1]+1,l=g[i].a; else h[i]=h[i+1];
for (int i=1,l,r,mid,ansl,ansr;i<=gcnt;i++)
if (f[i]!=f[i-1])
if (g[i].a==g[i].b) printf("%d\n",ref[g[i].b]),ans=1;
else {
l=1;r=i-1;ansl=0;
while (l<=r) {
mid=l+r>>1;
if (g[mid].b<g[i].b-1) l=mid+1,ansl=mid; else r=mid-1;
}
l=i+1;r=gcnt;ansr=n+1;
while (l<=r) {
mid=l+r>>1;
if (g[mid].a>g[i].b-1) r=mid-1,ansr=mid; else l=mid+1;
}
if (f[ansl]+1+h[ansr]>k) printf("%d\n",ref[g[i].b]),ans=1;
}
if (!ans) printf("-1\n");
}

最新文章

  1. hdu 5641 King&#39;s Phone
  2. 转载--tomcat整合apr
  3. Tomcat 6 —— Realm域管理
  4. datagrid后台分页js.js
  5. Python面向对象入门
  6. 采购订单限价(包含阶梯价)ME_PROCESS_PO_CUST
  7. PHP及Javascript 正则判断中文(转)
  8. C语言编程时常犯十八个错误
  9. mysql 编译安装提示“checking for termcap functions library... configure: error: No curses/termcap library found”
  10. 深入理解Android中ViewGroup
  11. Web API 2 对 CORS 的支持
  12. C#将制定文件夹下的PDF文件合并成一个并输出至指定路径
  13. MySQL GTID你知多少
  14. K3CLOUD数据权限授权
  15. 1.6 selenium3+firefox环境搭建
  16. mybatis电子商务平台b2b2c
  17. GuavaCache学习笔记二:Java四大引用类型回顾
  18. CSS 之 样式优先级机制
  19. SPOJ IM_Intergalactic Map
  20. About {DynamicResource {x:Static SystemColors.ControlBrushKey}}

热门文章

  1. React Hooks: useContext All In One
  2. git tag All In One
  3. Android Studio &amp; zh-Hans
  4. 教你玩转CSS Overflow
  5. C++ 多线程使用future传递异常
  6. 前端axios传递一个包含数组的对象到后台,后台可以用String接收,也可以用List集合接收
  7. Vuex入门、同步异步存取值进阶版
  8. Jquery hover鼠标经过时弹出div动态提示语
  9. Coposition 详解
  10. # PyComCAD介绍及开发方法