http://acm.hdu.edu.cn/showproblem.php?pid=2871 更新最左区间
2010-08-19 19:21
411 查看
/* 这题跟pku hotel 是一样的,只是询问没有那么明显 new w 可以先找到最左边长度为w的内存块,求的其最左边的下标l 然后 l 到 l + w - 1 这个区间进行更新 并且把l , l + w - 1 存入数组,方便Get Free 操作 */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #define LL(x) ((x) << 1) #define RR(x) ((x) << 1 | 1) using namespace std; const int N = 50005; struct Sed_tree { int l, r; int st; int lval, val, rval; int mid() { return (l + r) >> 1; } void doit() { if (st == 0) // 表示释放内存 lval = val = rval = dis(); else lval = val = rval = 0; } int dis() { return (r - l + 1); } } tree[N * 4]; struct Line { int start, end; } line ; int len; inline void Build(int l, int r, int node) { tree[node].l = l; tree[node].r = r; tree[node].st = -1; tree[node].lval = tree[node].val = tree[node].rval = tree[node].dis(); if (l == r) return; int mid = (l + r) >> 1; Build(l, mid, LL(node)); Build(mid + 1, r, RR(node)); } inline void Update(int l, int r, int node, int st) { if (l <= tree[node].l && tree[node].r <= r) { tree[node].st = st; tree[node].doit(); return; } if (tree[node].st != -1) { tree[LL(node)].st = tree[RR(node)].st = tree[node].st; tree[LL(node)].doit(); tree[RR(node)].doit(); tree[node].st = -1; } /* int mid = tree[node].mid(); if (l <= mid) Update(l, r, LL(node), st); if (mid < r) Update(l, r, RR(node), st); */ int mid = tree[node].mid(); if (r <= mid) { Update(l, r, LL(node), st); } else if (l > mid) { Update(l, r, RR(node), st); } else { Update(l, mid, LL(node), st); Update(mid + 1, r, RR(node), st); } tree[node].val = max(tree[LL(node)].rval + tree[RR(node)].lval, max( tree[LL(node)].val, tree[RR(node)].val)); tree[node].lval = tree[LL(node)].lval; tree[node].rval = tree[RR(node)].rval; if (tree[LL(node)].lval == tree[LL(node)].dis()) { tree[node].lval += tree[RR(node)].lval; } if (tree[RR(node)].rval == tree[RR(node)].dis()) { tree[node].rval += tree[LL(node)].rval; } } inline int Query(int node, int val) { if (tree[node].l == tree[node].r && val == 1) { return tree[node].l; } /* 这个快了15ms if (tree[node].l == tree[node].r) { if (tree[node].val == val) { return tree[node].l; } else { return -1; } */ if (tree[node].st != -1) { tree[LL(node)].st = tree[RR(node)].st = tree[node].st; tree[LL(node)].doit(); tree[RR(node)].doit(); tree[node].st = -1; } if (tree[LL(node)].val >= val) { return Query(LL(node), val); } else if (tree[LL(node)].rval + tree[RR(node)].lval >= val) { return tree[LL(node)].r - tree[LL(node)].rval + 1; } else if (tree[RR(node)].val >= val) { return Query(RR(node), val); } else { return -1; } } inline int Bin(int x) { int low = 1; int high = len - 1; int temp = -1; while (low <= high) { int mid = (low + high) >> 1; if (line[mid].start <= x) { temp = mid; low = mid + 1; } else { high = mid - 1; } } return temp; } int main() { int n, m; while (scanf("%d %d", &n, &m) != EOF) { len = 1; Build(1, n, 1); char str[10]; int p; while (m--) { scanf("%s", str); if (strcmp(str, "Reset") == 0) { len = 1; Update(1, n, 1, 0); printf("Reset Now/n"); continue; } scanf("%d", &p); if (strcmp(str, "New") == 0) { if (tree[1].val < p) { printf("Reject New/n"); } else { int temp = Query(1, p); printf("New at %d/n", temp); Update(temp, temp + p - 1, 1, 1);// 开辟这段区间的内存 /* 这里处理错了,一直wrong, 其实存在len = 1, 但是返回 tt = -1的情况的,返回 -1的时候我们要在line[1]插入 if (len == 1) { line[len].start = temp; line[len].end = temp + p - 1; len++; } else { int tt = Bin(temp); //printf("TT :: %d/n", tt); for (int i = len; i >= tt + 1; i--) { line[i] = line[i - 1]; } line[tt].start = temp;if(T[u].l==T[u].r)return T[u].l; int u2=u<<1; if(T[u2].c>=pos){ u=u2; } else{ pos-=T[u2].c; u=u2+1; line[tt].end = temp + p - 1; len++; } //printf("len :: %d/n", len); */ int tt = Bin(temp); if (tt == -1) { for (int i = len; i > 1; i--) line[i] = line[i - 1]; line[1].start = temp; line[1].end = temp + p - 1; } else { for (int i = len; i > tt + 1; i--) line[i] = line[i - 1]; line[tt + 1].start = temp; line[tt + 1].end = temp + p - 1; } len++; } } else if (strcmp(str, "Free") == 0) { int temp = Bin(p); if (temp == -1 || line[temp].end < p) { printf("Reject Free/n"); } else { printf("Free from %d to %d/n", line[temp].start, line[temp].end); Update(line[temp].start, line[temp].end, 1, 0);// 释放这段区间的内存 for (int i = temp; i < len; i++) { line[i] = line[i + 1]; } len--; //printf("len :: %d/n", len); } } else { if (p >= len) { printf("Reject Get/n"); } else { printf("Get at %d/n", line[p].start); } } } puts(""); } }
]/* * vector 不会用阿 */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #define LL(x) ((x) << 1) #define RR(x) ((x) << 1 | 1) using namespace std; const int N = 50005; struct Sed_tree { int l, r; int st; int lval, val, rval; int mid() { return (l + r) >> 1; } void doit() { if (st == 0) lval = val = rval = dis(); else lval = val = rval = 0; } int dis() { return (r - l + 1); } } tree[N * 4]; struct Line { int start, end; } ;//line ; //int len; vector<Line> df; inline void Build(int l, int r, int node) { tree[node].l = l; tree[node].r = r; tree[node].st = -1; tree[node].lval = tree[node].val = tree[node].rval = tree[node].dis(); if (l == r) return; int mid = (l + r) >> 1; Build(l, mid, LL(node)); Build(mid + 1, r, RR(node)); } inline void Update(int l, int r, int node, int st) { if (l <= tree[node].l && tree[node].r <= r) { tree[node].st = st; tree[node].doit(); return; } if (tree[node].st != -1) { tree[LL(node)].st = tree[RR(node)].st = tree[node].st; tree[LL(node)].doit(); tree[RR(node)].doit(); tree[node].st = -1; } int mid = tree[node].mid(); if (l <= mid) Update(l, r, LL(node), st); if (mid < r) Update(l, r, RR(node), st); /* if (r <= mid) { Update(l, r, LL(node), st); } else if (l > mid) { Update(l, r, RR(node), st); } else { Update(l, mid, LL(node), st); Update(mid + 1, r, RR(node), st); } */ tree[node].val = max(tree[LL(node)].rval + tree[RR(node)].lval, max( tree[LL(node)].val, tree[RR(node)].val)); tree[node].lval = tree[LL(node)].lval; tree[node].rval = tree[RR(node)].rval; if (tree[LL(node)].lval == tree[LL(node)].dis()) { tree[node].lval += tree[RR(node)].lval; } if (tree[RR(node)].rval == tree[RR(node)].dis()) { tree[node].rval += tree[LL(node)].rval; } } inline int Query(int node, int val) { /* if (tree[node].l == tree[node].r && val == 1) { return tree[node].l; } */ if (tree[node].l == tree[node].r) { if (tree[node].val == val) { return tree[node].l; } else { return -1; } } if (tree[node].st != -1) { tree[LL(node)].st = tree[RR(node)].st = tree[node].st; tree[LL(node)].doit(); tree[RR(node)].doit(); tree[node].st = -1; } if (tree[LL(node)].val >= val) { return Query(LL(node), val); } else if (tree[LL(node)].rval + tree[RR(node)].lval >= val) { return tree[LL(node)].r - tree[LL(node)].rval + 1; } else if (tree[RR(node)].val >= val) { return Query(RR(node), val); } else { return -1; } } /* inline int Bin(int x) { int low = 1; int high = len - 1; int temp = -1; while (low <= high) { int mid = (low + high) >> 1; if (line[mid].start <= x) { temp = mid; low = mid + 1; } else { high = mid - 1; } } return temp; } */ inline int Bin(int x) { int low = 0; int high = df.size() - 1; //int temp = -1; while (low <= high) { int mid = (low + high) >> 1; if (df[mid].start <= x) { //temp = mid; low = mid + 1; } else { high = mid - 1; } } return low; } int main() { int n, m; while (scanf("%d %d", &n, &m) != EOF) { //len = 1; df.clear(); Build(1, n, 1); char str[10]; int p; while (m--) { scanf("%s", str); if (strcmp(str, "Reset") == 0) { //len = 1; //Build(1, n, 1); df.clear(); Update(1, n, 1, 0); printf("Reset Now/n"); continue; } scanf("%d", &p); if (strcmp(str, "New") == 0) { //int temp = Query(1, p); if (tree[1].val < p) { printf("Reject New/n"); } else { int temp = Query(1, p); printf("New at %d/n", temp); Line line; line.start = temp; line.end = temp + p -1; int tt = Bin(temp); df.insert(df.begin() + tt, line); Update(temp, temp + p - 1, 1, 1); } } else if (strcmp(str, "Free") == 0) { int temp = Bin(p) - 1; //printf("==Free temp:%d/n", temp); if (temp == -1 || df[temp].end < p) { printf("Reject Free/n"); } else { printf("Free from %d to %d/n", df[temp].start, df[temp].end); Update(df[temp].start, df[temp].end, 1, 0); df.erase(df.begin() + temp, df.begin() + temp + 1); } } else { //int temp = Bin(p); //printf("==Get temp:%d/n", temp); int tt = df.size(); p--; if (p >= tt) { printf("Reject Get/n"); } else { printf("Get at %d/n", df[p].start); } } } puts(""); } }
相关文章推荐
- http://acm.hdu.edu.cn/showproblem.php?pid=1779 线段树 求区间最大值 结点更新
- http://acm.hdu.edu.cn/showproblem.php?pid=1540 更新节点,询问节点所在的位置有多少连续的区间
- http://acm.hdu.edu.cn/showproblem.php?pid=1541 结点更新求最左区间的个数
- http://acm.hdu.edu.cn/showproblem.php?pid=1754 更新节点,区间最值
- http://acm.hdu.edu.cn/showproblem.php?pid=1166 更新节点,区间求和
- 二分查找求函数的区间最小值&&http://acm.hdu.edu.cn/showproblem.php?pid=2899
- http://acm.hdu.edu.cn/showproblem.php?pid=1698 成段更新,总区间求和
- http://acm.hdu.edu.cn/showproblem.php?pid=2795 更新节点构造线段数很关键,询问特殊
- http://acm.hdu.edu.cn/showproblem.php?pid=2795&&线段树之求最小区间端点值
- http://acm.hdu.edu.cn/showproblem.php?pid=3450 线段树 + dp
- 二维背包:http://acm.hdu.edu.cn/showproblem.php?pid=3303
- http://acm.hdu.edu.cn/showproblem.php?pid=1272。。。
- 最大连续子序列http://acm.hdu.edu.cn/showproblem.php?pid=1231
- hdu 1085 http://acm.hdu.edu.cn/showproblem.php?pid=1085
- http://acm.hdu.edu.cn/showproblem.php?pid=1269
- http://acm.hdu.edu.cn/showproblem.php?pid=2363
- http://acm.hdu.edu.cn/showproblem.php?pid=2094
- HDU 1702 队列与栈的简单运用http://acm.hdu.edu.cn/showproblem.php?pid=1702
- http://acm.hdu.edu.cn/webcontest/contest_showproblem.php?pid=1004&ojid=2&cid=963&hide=0
- http://acm.hdu.edu.cn/showproblem.php?pid=1787 典型 欧拉函数(为何c++ 那样会RE)