HDU
来源:互联网 发布:淘宝好听的用户名大全 编辑:程序博客网 时间:2024/05/29 09:49
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4553
题目思路:本题就是一个线段树的区间合并,定义三个懒惰标记:屌丝标记,女神标记,学习标记,三个的优先级为学习 > 女神 > 屌丝,更新时按照这个优先级更新即可,查询时,屌丝就直接查看屌丝区间是否有空闲时间,女神优先看屌丝区间和女神区间是否有空闲时间,否则就覆盖已有的屌丝区间,学习就是将屌丝区间和女神区间内的所有值清空,具体操作代码里都有解释。
AC代码如下:
#include <bits/stdc++.h>#define INF 0x3f3f3f3f#define FIN freopen("in.txt","r",stdin)#define fuck(x) cout<<'['<<x<<']'<<endl#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;typedef long long LL;typedef pair<int, int>pii;const int MX = 1e5 + 10;struct node { int n, d, s;//n代表女神的懒惰标记,d代表屌丝的懒惰标记,s代表学习的懒惰标记; int nls, nrs, nms;//分别代表女神的左连续最长区间,右连续最长区间和总连续最长区间; int dls, drs, dms;//分别代表屌丝的左连续最长区间,右连续最长区间和总连续最长区间;} a[MX << 2];//所储存的是可用的空闲时间是多少,方便查询;void update_d(int rt) { a[rt].d = 1; a[rt].dls = a[rt].drs = a[rt].dms = 0;}void update_n(int rt) { a[rt].n = 1; a[rt].d = 0; a[rt].nls = a[rt].nrs = a[rt].nms = 0; a[rt].dls = a[rt].drs = a[rt].dms = 0;//女神的优先级高于屌丝,所以更新女神时也要把屌丝的区间长度也更新;}void update_s(int l, int r, int rt) { a[rt].s = 1; a[rt].d = a[rt].n = 0; a[rt].dls = a[rt].drs = a[rt].dms = r - l + 1; a[rt].nls = a[rt].nrs = a[rt].nms = r - l + 1; //学习的优先级最高,所以更新时需将整个区间内女神和屌丝的所有标记都更新掉;}void Push_Up(int l, int r, int rt) { int m = (l + r) >> 1; a[rt].dms = max(a[rt << 1].dms, max(a[rt << 1 | 1].dms, a[rt << 1].drs + a[rt << 1 | 1].dls)); //父节点的总连续区间长度 = MAX(左儿子的左连续最长区间,右儿子的右连续最长区间,左儿子的右连续区间 + 右儿子的左连续最长区间); a[rt].dls = a[rt << 1].dls; a[rt].drs = a[rt << 1 | 1].drs; if(a[rt].dls == m - l + 1)//如果左儿子的左连续最长区间是满的,那么父节点的左连续最长区间要加上右儿子的左连续最长区间; a[rt].dls += a[rt << 1 | 1].dls; if(a[rt].drs == r - m)//右儿子同理; a[rt].drs += a[rt << 1].drs; a[rt].nms = max(a[rt << 1].nms, max(a[rt << 1 | 1].nms, a[rt << 1].nrs + a[rt << 1 | 1].nls)); a[rt].nls = a[rt << 1].nls; a[rt].nrs = a[rt << 1 | 1].nrs; if(a[rt].nls == m - l + 1) a[rt].nls += a[rt << 1 | 1].nls; if(a[rt].nrs == r - m) a[rt].nrs += a[rt << 1].nrs;}void Push_Down(int l, int r, int rt) { int m = (l + r) >> 1; if(a[rt].s) { update_s(lson); update_s(rson); a[rt].s = 0; }//更新时学习的优先级最高,优先更新; if(a[rt].n) { update_n(rt << 1); update_n(rt << 1 | 1); a[rt].n = 0; }//女神优先级第二,接着更新女神; if(a[rt].d) { update_d(rt << 1); update_d(rt << 1 | 1); a[rt].d = 0; }//最后更新屌丝;}void study(int L, int R, int l, int r, int rt) { if(L <= l && r <= R) { update_s(l, r, rt); return; } int m = (l + r) >> 1; Push_Down(l, r, rt); if(L <= m) study(L,R,lson); if(R > m) study(L,R,rson); Push_Up(l, r, rt);}void Update(int L, int R, int c, int l, int r, int rt) { if(L <= l && r <= R) { if(c == 0)//0代表屌丝; update_d(rt); else update_n(rt); return; } int m = (l + r) >> 1; Push_Down(l, r, rt); if(L <= m) Update(L,R,c,lson); if(R > m) Update(L,R,c,rson); Push_Up(l, r, rt);}int Query(int w, int f, int l, int r, int rt) { if(l == r) return l; Push_Down(l, r, rt); int m = (l + r) >> 1; if(f == 0) { if(a[rt << 1].dms >= w) return Query(w, f, lson);//如果左儿子的总连续区间大于所要的长度,则往左儿子更新; else if(a[rt << 1].drs + a[rt << 1 | 1].dls >= w) return m - a[rt << 1].drs + 1;//如果是合并后的区间大于所要长度,则直接返回; else return Query(w, f, rson);//如果右儿子的总连续区间大于所要的长度,则往右儿子更新; } else {//女神的查询同理; if(a[rt << 1].nms >= w) return Query(w, f, lson); else if(a[rt << 1].nrs + a[rt << 1 | 1].nls >= w) return m - a[rt << 1].nrs + 1; else return Query(w, f, rson); }}int T;int n, m;int main() { // FIN; scanf("%d", &T); int cas = 1; while(T--) { scanf("%d%d", &n, &m); study(1, n, 1, n, 1); printf("Case %d:\n", cas++); while(m--) { char op[10]; int x, y; scanf("%s", op); if(op[0] == 'D') { scanf("%d", &x); if(a[1].dms < x)//如果可用的时间不够,直接输出; puts("fly with yourself"); else { int ans = Query(x, 0, 1, n, 1); Update(ans, ans + x - 1, 0, 1, n, 1); printf("%d,let's fly\n", ans); } } else if(op[0] == 'N') { scanf("%d", &x); if(a[1].dms < x) {//如果屌丝区间剩余的时间不够,则查看女神区间; if(a[1].nms < x) puts("wait for me"); else { int ans = Query(x, 1, 1, n, 1); Update(ans, ans + x - 1, 1, 1, n, 1); printf("%d,don't put my gezi\n", ans); } } else{//否则直接占用屌丝区间的时间; int ans = Query(x,0,1,n,1); Update(ans,ans + x - 1,1,1,n,1); printf("%d,don't put my gezi\n", ans); } } else { scanf("%d%d", &x, &y); study(x, y, 1, n, 1); puts("I am the hope of chinese chengxuyuan!!"); } } } return 0;}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- python编程从入门到实践 习题12-3 火箭
- Android开发使用https及Webview访问https页面
- ztree自定义单选框
- Android进阶#(7/12)装点程序“门面”——代码规范_命名+编码建议
- JavaWeb:报错信息The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- HDU
- poj-1191-棋盘分割
- css基本操作
- Head First设计模式学习笔记
- 第四篇:深入浅出UML类图(一)
- vba中的自动筛选(atuo filter) 实现(realize)
- 301和302跳转的区别
- spark学习笔记:考察集群的文件读取机制
- 【23种设计模式】创建型模式 > 单例模式