您的位置:首页 > 理论基础 > 计算机网络

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("");
}
}
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  tree query build struct vector
相关文章推荐