NBOJv2 1004 蛤玮打扫教室(线段树区间更新区间最值查询)
2016-07-21 16:26
441 查看
Problem 1004: 蛤玮打扫教室
Time Limits: 1000 MS Memory Limits: 65536 KB64-bit interger IO format: %lld Java
class name: Main
Description
现在知道一共有n个机房,算上蛤玮一共有m个队员,教练做了m个签,每个签上写着两个数L,R(L<=R),抽到的人要把[L,R]的教室全部打扫一遍.由于蛤玮是队长而且他很懒,他通过某种交易提前知道了所有m个签上面写的是什么,而且通过某种魔法可以控制自己抽到哪个签.一个教室被打扫一次就干净了,所以蛤玮想知道自己抽哪些签可以不用打扫教室而且不会被教练发现,即他抽到的区间全都会被别人打扫一遍.蛤玮被教练叫去打扫机房,集训队有很多机房,也有很多队员,现在他们要用抽签的方式决定谁打扫哪间教室.
Input
第一行为一个整数T(1<=T<=20),代表数据组数。每组数据第一行n,m(1<=n,m<=100000),接下来m行,每行两个数L,R(1<=L<=R<=n).
Output
每组数据输出一个k,表示多少个签符合蛤玮的要求,接下来一行输出k个数,这些签的编号,下标从1开始.
Sample Input
3 15 5 1 4 5 5 6 8 9 10 5 6 3 6 1 1 1 1 2 2 2 2 3 3 3 3 10 3 1 4 2 6 6 10
Output for Sample Input
2 2 5 6 1 2 3 4 5 6 0
最近学了线段树,把以前的题目都拿出来再做了一遍,虽然说时间并比离散化的做法慢很多……主要是熟悉熟悉,这题用线段树就是区间更新,区间最(小)值查询,因为一个区间只有被至少打扫两次才能被选入,也就是选某些区间的最小值大于等于2的即可,pushdown函数稍微修改一下就好了
代码:
#include<iostream> #include<algorithm> #include<cstdlib> #include<sstream> #include<cstring> #include<cstdio> #include<string> #include<deque> #include<stack> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; #define INF 0x3f3f3f3f #define MM(x,y) memset(x,y,sizeof(x)) #define LC(x) (x<<1) #define RC(x) ((x<<1)+1) #define MID(x,y) ((x+y)>>1) typedef pair<int,int> pii; typedef long long LL; const double PI=acos(-1.0); const int N=100010; struct info { int l,mid,r; int maxm,add; }; info T[N<<2]; void pushup(int k) { T[k].maxm=min(T[LC(k)].maxm,T[RC(k)].maxm); } void pushdown(int k) { T[LC(k)].add+=T[k].add; T[RC(k)].add+=T[k].add; T[LC(k)].maxm+=T[k].add; T[RC(k)].maxm+=T[k].add; T[k].add=0; } void build(int k,int l,int r) { T[k].l=l; T[k].r=r; T[k].mid=MID(l,r); T[k].add=0; T[k].maxm=0; if(l==r) return ; build(LC(k),l,T[k].mid); build(RC(k),T[k].mid+1,r); } void update(int k,int l,int r,int v) { if(r<T[k].l||l>T[k].r) return ; if(l<=T[k].l&&r>=T[k].r) { T[k].add+=v; T[k].maxm+=v; } else { if(T[k].add) pushdown(k); update(LC(k),l,r,v); update(RC(k),l,r,v); pushup(k); } } int query(int k,int l,int r) { if(l<=T[k].l&&r>=T[k].r) return T[k].maxm; if(T[k].add) pushdown(k); if(r<=T[k].mid) return query(LC(k),l,r); else if(l>T[k].mid) return query(RC(k),l,r); else return min(query(LC(k),l,T[k].mid),query(RC(k),T[k].mid+1,r)); } pii seg ; int main(void) { int tcase,n,m,l,r,i,j,cnt; scanf("%d",&tcase); while (tcase--) { scanf("%d%d",&n,&m); build(1,1,n); for (i=1; i<=m; i++) { scanf("%d%d",&seg[i].first,&seg[i].second); update(1,seg[i].first,seg[i].second,1); } vector<int>r; for (i=1; i<=m; i++) { int m=query(1,seg[i].first,seg[i].second); if(m>=2) r.push_back(i); } cnt=r.size(); printf("%d\n",cnt); for (i=0; i<cnt; i++) printf("%d%s",r[i],i==cnt-1?"\n":" "); } return 0; }
相关文章推荐
- 朴素贝叶斯分类器
- twoWay使用
- vb.net实现Vb中的Any变体类型
- 静态多态入门示例
- shell学习--[、test测试的使用
- java POI 实现合并单元格
- Linux shell encyclopedia, very useful
- linux 系统 分级命令目录作用,软硬中断,查看具体进程启动信息
- java语言基础入门——继承及多态
- locate: can not stat () `/var/lib/mlocate/mlocate.db': No such file or directory
- 用openvswitch创建docker容器之间的vxlan网络
- 字符串与数值、字符数组之间的转换
- 模拟缓冲区方法MyBufferedReaderDemo()
- Hadoop-2.4.1学习之Mapper和Reducer
- 利用CTS框架实现APP的自动化白盒测试
- Java Cookie工具类代码
- 第15章 磁盘配额(Quota)与高级文件系统管理
- 118. Pascal's Triangle
- mif_maker2010.exe下载和使用说明
- 【转】Hadoop安全实践