线段树专辑—— hdu 2871 Memory Control

http://acm.hdu.edu.cn/showproblem.php?pid=2871

求解区间内连续空闲区间!

题目有四种操作:

1、New X,查找一个有x连续空间的区间,并返回区间的首位置,要求答案尽量考前。如果找不到x的连续空间,则返回“Reject New”。

这是最基础的线段树操作。和pku 3667、hdu 1540一样的过程

2、Free X,释放第x个记忆片段,所谓第x个第一片段,指的是剩余的记忆片段中,相对来说第x次 “New x” 的结果。将其区间跟新即可,关于这道题,记录第x个记忆片段是需要技巧的,直接用数组模拟无疑是找死。纠结了许久以后,还是看了别人的结题报告,人家都是用的vector容器,不太会,学习了一下。。。

3、Get x,输出第X个记忆片段的首位置

4、Reset,重新置0,将线段树整体跟新一下即可

 

介绍一下利用vector容器如何实现二分时间的查找!

首先,定义一个记录左右端点结构的vector容器

struct NODE { int l; int r; }; vector<NODE>mery;

接下来,定义该结构的排序函数

bool cmp(const NODE &a,const NODE &b) { return a.l<b.l; }

假设我们已经有了[1,3]、[7,8]、[11,15]三个记忆片段,并且他们已经储存在mery中了。现在我们要插入记忆片段[4,6],那么我们该将它插入到哪个位置呢?

从肉眼看,我们简单的看到应该插入到[1,3]和[7,8]中间,那么该如何处理呢?

首先定义一个关于NODE的vector的迭代器(俗称指针) 

vector<NODE>::iterator it;

接下来调用一个叫做 upper_bound()的函数,这个函数是一个类函数,各种数据都能处理,它的作用是在一个数组中,给它一个x,它将返回第一个比x大的数的位置所在!

it=upper_bound(mery.begin(),mery.end(),b,cmp);  //从开始到结尾根据cmp原则查找第一个比b大的数据所在的位置

这样,it 便保存着[1,3]、[7,8]中间那个地方的位置了,最后我们只需要 mery.insert(it,b); 这就把[4,6]插入到了对应的位置    //b所代表的就是[4,6]


最后再介绍一下如何删除指定位置的数据:

首先依然是利用upper_bound()函数找到某个数据在vector中的位置,由于该函数返回的是第一个大于该数据的地址,所以记得将结果减一即可!

it=upper_bound(mery.begin(),mery.end(),b,cmp);

int temp=it-mery.begin()-1;  //指针减指针得到一个常数值,该值既是下标,再减一得到准确地址

mery.erase(mery.begin()+temp); 


 

View Code
  1 #include<iostream>
2 #include<string>
3 #include<vector>
4 #include<algorithm>
5 using namespace std;
6
7 struct node
8 {
9 int l;
10 int r;
11 int cover;
12 int lval;
13 int rval;
14 int maxval;
15 };
16
17 node tree[250000];
18 int n,m;
19 int v[50000];
20
21 struct NODE
22 {
23 int l;
24 int r;
25 };
26 vector<NODE>mery;
27
28 int max(int a,int b)
29 {
30 return a>b?a:b;
31 }
32
33 bool cmp(const NODE &a,const NODE &b)
34 {
35 return a.l<b.l;
36 }
37
38 void build(int i,int l,int r)
39 {
40 tree[i].l=l;
41 tree[i].r=r;
42 tree[i].cover=0;
43 tree[i].lval=tree[i].rval=tree[i].maxval=(r-l+1);
44 if(l==r)
45 return;
46 int mid=(l+r)/2;
47 build(2*i,l,mid);
48 build(2*i+1,mid+1,r);
49 }
50
51 void fun(int i,int w)
52 {
53 if(w==0)
54 tree[i].rval=tree[i].lval=tree[i].maxval=(tree[i].r-tree[i].l+1);
55 else
56 tree[i].rval=tree[i].lval=tree[i].maxval=0;
57 }
58
59 void updata(int i,int l,int r,int w)
60 {
61 if(tree[i].l>r || tree[i].r<l)
62 return;
63 if(tree[i].l>=l && tree[i].r<=r)
64 {
65 tree[i].cover=w;
66 fun(i,w);
67 return;
68 }
69 if(tree[i].cover!=-1)
70 {
71 tree[2*i].cover=tree[2*i+1].cover=tree[i].cover;
72 fun(2*i,tree[i].cover);
73 fun(2*i+1,tree[i].cover);
74 }
75 updata(2*i,l,r,w);
76 updata(2*i+1,l,r,w);
77 if(tree[2*i].cover==0 && tree[2*i+1].cover==0)
78 tree[i].cover=0;
79 else if(tree[2*i].cover==1 && tree[2*i+1].cover==1)
80 tree[i].cover=1;
81 else
82 tree[i].cover=-1;
83 tree[i].lval=tree[2*i].lval+(tree[2*i].cover==0?tree[2*i+1].lval:0);
84 tree[i].rval=tree[2*i+1].rval+(tree[2*i+1].cover==0?tree[2*i].rval:0);
85 tree[i].maxval=max(max(tree[2*i].maxval,tree[2*i+1].maxval),(tree[2*i].rval+tree[2*i+1].lval));
86 }
87
88 int query(int i,int w)
89 {
90 if(tree[i].cover==0 && tree[i].lval>=w)
91 return tree[i].l;
92 else if(tree[i].cover==1)
93 return 0;
94 else if(tree[i].cover==-1)
95 {
96 if(tree[2*i].maxval>=w)
97 return query(2*i,w);
98 else if(tree[2*i].rval+tree[2*i+1].lval>=w)
99 {
100 return tree[2*i].r-tree[2*i].rval+1;
101 }
102 else if(tree[2*i+1].maxval>=w)
103 return query(2*i+1,w);
104 }
105 return 0;
106 }
107
108
109
110 int main()
111 {
112 int i,a,ans;
113 char str[6];
114 NODE b;
115 //freopen("in.txt","r",stdin);
116 while(scanf("%d%d",&n,&m)==2)
117 {
118 build(1,1,n);
119 mery.clear();
120 for(i=0;i<m;i++)
121 {
122 scanf("%*c");
123 scanf("%s",str);
124 if(str[0]=='R')
125 {
126 updata(1,1,n,0);
127 printf("Reset Now\n");
128 mery.clear();
129 }
130 else if(str[0]=='N')
131 {
132 scanf("%d",&a);
133 ans=query(1,a);
134 if(ans>0)
135 {
136 printf("New at %d\n",ans);
137 updata(1,ans,ans+a-1,1);
138 b.l=ans;b.r=ans+a-1;
139 vector<NODE>::iterator it;
140 it=upper_bound(mery.begin(),mery.end(),b,cmp);
141 mery.insert(it,b);
142 }
143 else
144 {
145 printf("Reject New\n");
146 }
147 }
148 else if(str[0]=='F')
149 {
150 scanf("%d",&a);
151 b.l=a;
152 b.r=a;
153 vector<NODE>::iterator it;
154 it=upper_bound(mery.begin(),mery.end(),b,cmp);
155 int temp=it-mery.begin()-1;
156 if(temp==-1 || mery[temp].r<a)
157 printf("Reject Free\n");
158 else
159 {
160 printf("Free from %d to %d\n",mery[temp].l,mery[temp].r);
161 updata(1,mery[temp].l,mery[temp].r,0);
162 mery.erase(mery.begin()+temp);
163 }
164 }
165 else if(str[0]=='G')
166 {
167 scanf("%d",&a);
168 if(a>mery.size())
169 {
170 printf("Reject Get\n");
171 }
172 else
173 {
174 printf("Get at %d\n",mery[a-1].l);
175 }
176 }
177 }
178 printf("\n");
179 }
180 return 0;
181 }



posted @ 2011-11-12 15:29  Accept  阅读(317)  评论(0编辑  收藏  举报