hdu 4614(区间更新)
2015-08-28 23:55
211 查看
这里写代码片题意:有n个花瓶编号从0到n-1,初始花瓶都是空的,然后有两个操作,1 a b表示从位置a开始往后面找b(不够b个也可以)个空花瓶插花,输出插花的首位置和末位置,2 a b表示输出区间[a,b]有多少个花,并且把这个区间内所有花都拿走。
题解:很容易想到用线段树维护区间内有多少个空花瓶,然后操作2可以直接用普通的区间查询和区间修改,操作1可以看作先查询前a-1个花瓶有num个是空的,然后查询第num+1和第num+b个空花瓶的位置,这个查询也可以用线段树查询或二分查找来写。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 50005; int n, q, tree[N << 2], flag[N << 2]; void pushup(int k) { tree[k] = tree[k * 2] + tree[k * 2 + 1]; } void pushdown(int k, int left, int right) { if (flag[k] == 1) { flag[k * 2] = flag[k * 2 + 1] = flag[k]; tree[k * 2] = tree[k * 2 + 1] = 0; flag[k] = 0; } else if (flag[k] == 2) { int mid = (left + right) / 2; flag[k * 2] = flag[k * 2 + 1] = flag[k]; tree[k * 2] = mid - left + 1; tree[k * 2 + 1] = right - mid; flag[k] = 0; } } void build(int k, int left, int right) { flag[k] = 0; tree[k] = right - left + 1; if (left != right) { int mid = (left + right) / 2; build(k * 2, left, mid); build(k * 2 + 1, mid + 1, right); } } void modify(int k, int left, int right, int l, int r, int x) { if (l <= left && right <= r) { flag[k] = x; if (x == 1) tree[k] = 0; else tree[k] = right - left + 1; return; } pushdown(k, left, right); int mid = (left + right) / 2; if (l <= mid) modify(k * 2, left, mid, l, r, x); if (r > mid) modify(k * 2 + 1, mid + 1, right, l, r, x); pushup(k); } int query(int k, int left, int right, int l, int r) { if (l <= left && right <= r) return tree[k]; pushdown(k, left, right); int mid = (left + right) / 2, res = 0; if (l <= mid) res += query(k * 2, left, mid, l, r); if (r > mid) res += query(k * 2 + 1, mid + 1, right, l, r); pushup(k); return res; } int Find(int k, int left, int right, int l, int r, int pos) { if (left == right) return left; pushdown(k, left, right); int mid = (left + right) / 2, temp; if (r <= mid) temp = Find(k * 2, left, mid, l, r, pos); else if (l > mid) temp = Find(k * 2 + 1, mid + 1, right, l, r, pos); else { if (pos <= tree[k * 2]) temp = Find(k * 2, left, mid, l, r, pos); else temp = Find(k * 2 + 1, mid + 1, right, l, r, pos - tree[k * 2]); } pushup(k); return temp; } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &q); build(1, 0, n - 1); int op, l, x; while (q--) { scanf("%d%d%d", &op, &l, &x); if (op == 1) { int temp = query(1, 0, n - 1, l, n - 1); if (!temp) { printf("Can not put any one.\n"); continue; } else if (temp <= x) x = temp; int num = 0; if (l >= 1) num = query(1, 0, n - 1, 0, l - 1); int st = Find(1, 0, n - 1, 0, n - 1, num + 1); int en = Find(1, 0, n - 1, 0, n - 1, num + x); printf("%d %d\n", st, en); modify(1, 0, n - 1, st, en, 1); } else { printf("%d\n", x - l + 1 - query(1, 0, n - 1, l, x)); modify(1, 0, n - 1, l, x, 2); } } printf("\n"); } return 0; }
相关文章推荐
- 杭电1869-六度分离(最短路径,dijkstra,spfa,floyd)
- [LeetCode#212]Word Search II
- 微信读书来了,说好的全民刷书呢?
- Linux备份与恢复
- 企业管理之客户之道
- vsftpd遇到“refusing to run with writable root inside chroot”错误
- RESTful HTTP的实践
- JSOI2013编程作业
- XenDesktop 设置上班高峰期前预先启动虚拟桌面
- oracle之安装
- My Booklist
- Hadoop里的数据挖掘应用-Mahout——学习笔记<三>
- swift - The Proxy Pattern
- 信号量 互斥锁 条件变量的区别
- OSPF特殊区域之totally stub
- 开源框架-ormlite-android数据库的使用
- iOS之Operation Queues 和 Grand Central Dispatch
- 华为OJ题2---字符串最后一个单词的长度
- 详解连接SQL Server数据库的方法,并使用Statement接口实现对数据库的增删改操作
- Spark的Python和Scala shell介绍(翻译自Learning.Spark.Lightning-Fast.Big.Data.Analysis)