HDU - 4553 约会安排(线段树 区间合并)
2015-10-21 23:18
429 查看
题目大意:中文题意
解题思路:设计三个mark,一个是女神的,一个是学习的,一个是基友的,其中优先级是学习<基友<女神,更新的时候按照优先级更新
区间维护六个数,一个是左连续的最长空闲时间,一个是右连续的最长空闲时间,一个是最长空闲时间,三个时间,一个是基友的,一个是女神的,所以共6个
询问的时候,如果是基友的话,直接判断总的基友的连续时间,如果时间够的话,就找出,输出并更新。反之,则另外输出
如果是女神的,先判断一下基友的连续时间,如果够的话,从中得到该时间,输出并修改
如果不够,就判断一下女神的连续时间
解题思路:设计三个mark,一个是女神的,一个是学习的,一个是基友的,其中优先级是学习<基友<女神,更新的时候按照优先级更新
区间维护六个数,一个是左连续的最长空闲时间,一个是右连续的最长空闲时间,一个是最长空闲时间,三个时间,一个是基友的,一个是女神的,所以共6个
询问的时候,如果是基友的话,直接判断总的基友的连续时间,如果时间够的话,就找出,输出并更新。反之,则另外输出
如果是女神的,先判断一下基友的连续时间,如果够的话,从中得到该时间,输出并修改
如果不够,就判断一下女神的连续时间
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 100010 << 2; struct Tree{ int n, d, s;//女神标记n,屌丝标记d,学习标记s int dls, drs, das;//屌丝的左连续最长,右连续最长,总连续最长 int nls, nrs, nas;//女神的左连续最长,右连续最长,总连续最长 }tree ; int n, q; void Diaosi(int u) { tree[u].d = 1; tree[u].dls = tree[u].drs = tree[u].das = 0; } void Nvshen(int u) { tree[u].n = 1; tree[u].d = 0; tree[u].nls = tree[u].nrs = tree[u].nas = 0; tree[u].dls = tree[u].drs = tree[u].das = 0; } void PushUp(int u, int l, int r) { int mid = (l + r) >> 1; tree[u].das = max(tree[u << 1].das, max(tree[u << 1 | 1].das, tree[u << 1].drs + tree[u << 1 | 1].dls)); tree[u].dls = tree[u << 1].dls; tree[u].drs = tree[u << 1 | 1].drs; if (tree[u].dls == mid - l + 1) tree[u].dls += tree[u << 1 | 1].dls; if (tree[u].drs == r - mid) tree[u].drs += tree[u << 1].drs; tree[u].nas = max(tree[u << 1].nas, max(tree[u << 1 | 1].nas, tree[u << 1].nrs + tree[u << 1 | 1].nls)); tree[u].nls = tree[u << 1].nls; tree[u].nrs = tree[u << 1 | 1].nrs; if (tree[u].nls == mid - l + 1) tree[u].nls += tree[u << 1 | 1].nls; if (tree[u].nrs == r - mid) tree[u].nrs += tree[u << 1].nrs; } void StudyTime(int u, int l, int r) { tree[u].s = 1; tree[u].n = tree[u].d = 0; tree[u].dls = tree[u].drs = tree[u].das = r - l + 1; tree[u].nls = tree[u].nrs = tree[u].nas = r - l + 1; } void PushDown(int u, int l, int r) { int mid = (l + r) >> 1; if (tree[u].s) { StudyTime(u << 1, l, mid); StudyTime(u << 1 | 1, mid + 1, r); tree[u].s = 0; } if (tree[u].d) { Diaosi(u << 1); Diaosi(u << 1 | 1); tree[u].d = 0; } if (tree[u].n) { Nvshen(u << 1); Nvshen(u << 1 | 1); tree[u].n = 0; } } void study(int u, int l, int r, int L, int R) { if (l == L && r == R) { StudyTime(u, l, r); return ; } int mid = (l + r) >> 1; PushDown(u, l, r); if (R <= mid) study(u << 1, l, mid, L, R); else if (L > mid) study(u << 1 | 1, mid + 1, r, L, R); else { study(u << 1, l, mid, L, mid); study(u << 1 | 1, mid + 1, r, mid + 1, R); } PushUp(u, l, r); } void Modify(int u, int l, int r, int L, int R, int f) { if (l == L && r == R) { if (f == 0) Diaosi(u); else Nvshen(u); return ; } int mid = (l + r) >> 1; PushDown(u, l, r); if (R <= mid) Modify(u << 1, l, mid, L, R, f); else if (L > mid) Modify(u << 1 | 1, mid + 1, r, L, R, f); else { Modify(u << 1, l, mid, L, mid, f); Modify(u << 1 | 1, mid + 1, r, mid + 1, R, f); } PushUp(u, l, r); } int Query(int u, int l, int r, int w, int f) { if (l == r) return l; int mid = (l + r) >> 1; PushDown(u, l, r); if (f == 0) { if (tree[u << 1].das >= w) return Query(u << 1, l, mid, w, f); else if (tree[u << 1].drs + tree[u << 1 | 1].dls >= w) return mid - tree[u << 1].drs + 1; else return Query(u << 1 | 1, mid + 1, r, w, f); } else { if (tree[u << 1].nas >= w) return Query(u << 1, l, mid, w, f); else if (tree[u << 1].nrs + tree[u << 1 | 1].nls >= w) return mid - tree[u << 1].nrs + 1; else return Query(u << 1 | 1, mid + 1, r, w, f); } } void solve() { char op[10]; int x, y; while (q--) { scanf("%s", op); if (op[0] == 'D') { scanf("%d", &x); if (tree[1].das < x) printf("fly with yourself\n"); else { int ans = Query(1, 1, n, x, 0); Modify(1, 1, n, ans, ans + x - 1, 0); printf("%d,let's fly\n", ans); } } else if (op[0] == 'N') { scanf("%d", &x); if (tree[1].das < x) { if (tree[1].nas < x) printf("wait for me\n"); else { int ans = Query(1, 1, n, x, 1); Modify(1, 1, n, ans, ans + x - 1, 1); printf("%d,don't put my gezi\n", ans); } } else { int ans = Query(1, 1, n, x, 0); Modify(1, 1, n, ans, ans + x - 1, 1); printf("%d,don't put my gezi\n", ans); } } else { scanf("%d%d", &x, &y); study(1, 1, n, x, y); printf("I am the hope of chinese chengxuyuan!!\n"); } } } int main() { int test, cas = 1; scanf("%d", &test); while (test--) { printf("Case %d:\n", cas++); scanf("%d%d", &n, &q); study(1, 1, n, 1, n); solve(); } return 0; }
相关文章推荐
- struts技术有什么优点、好处?
- JAVA多线程--信号量(Semaphore)
- 【算法设计与数据结构】三分法:求单峰函数的极值
- 王小胖之 Base64编码/解码
- Python -- 生成器
- 深入理解Java的接口和抽象类
- Java记录 -42- Java Collection
- 【线性代数公开课MIT Linear Algebra】 第九课 向量与矩阵的桥梁
- 编码问题
- RS485总线典型电路介绍
- Java 7 的7个新特性
- 黑马程序员——Java基础语法 之函数,数组
- Strcat,strcpy,strcmp,Strlen函数原型
- Ubuntu中配置squid代理
- Office文档密码破解(如忘记 outlook pst文件的密码)
- CUDA block 中的同步,fence 和原子操作
- 满足条件的周长最短的三条边
- struts2常用标签详解-在项目中使用struts2标签
- 关于luci的几个问题<二>
- 【堆】