(线段树,二分)hdoj 2871-Memory Control
Posted 惜取少年时
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(线段树,二分)hdoj 2871-Memory Control相关的知识,希望对你有一定的参考价值。
A sequence of memory units is called a memory block.
The memory control system we consider now has four kinds of operations:
1. Reset Reset all memory units free.
2. New x Allocate a memory block consisted of x continuous free memory units with the least start number
3. Free x Release the memory block which includes unit x
4. Get x Return the start number of the xth memory block(Note that we count the memory blocks allocated from left to right)
Where 1<=x<=N.You are request to find out the output for M operations.
InputInput contains multiple cases.
Each test case starts with two integer N,M(1<=N,M<=50000) ,indicating that there are N units of memory and M operations.
Follow by M lines,each line contains one operation as describe above.
OutputFor each “Reset” operation, output “Reset Now”.
For each “New” operation, if it’s possible to allocate a memory block,
output “New at A”,where Ais the least start number,otherwise output “Reject New”.
For each “Free” operation, if it’s possible to find a memory block occupy unit x,
output “Free from A to B”,where A and B refer to the start and end number of the memory block,otherwise output “Reject Free”.
For each “Get” operation, if it’s possible to find the xth memory blocks,
output “Get at A”,where A is its start number,otherwise output “Reject Get”.
Output one blank line after each test case.
Sample Input
6 10 New 2 New 5 New 2 New 2 Free 3 Get 1 Get 2 Get 3 Free 3 Reset
Sample Output
New at 1 Reject New New at 3 New at 5 Free from 3 to 4 Get at 1 Get at 5 Reject Get Reject Free Reset Now
区间维护依旧与Hotel题目类似。变得更加复杂的是对Free get操作时区间的维护。采用引入vector记录区间的办法,为了提高效率,每次查询、插入都需要采用二分法(利用了vector插入时是在
给定地址前插入数据的特性)这种二分法的使用值得复习反思。
1 #include <iostream> 2 //#include<bits/stdc++.h> 3 #include <stack> 4 #include <queue> 5 #include <map> 6 #include <set> 7 #include <cstdio> 8 #include <cstring> 9 #include <algorithm> 10 #include <math.h> 11 using namespace std; 12 int N,M; 13 const int MAX=5e4+5; 14 struct node 15 { 16 int left,right,mid; 17 int al,ar; 18 int status; 19 int len() 20 { 21 return ar-al+1; 22 } 23 void actl() 24 { 25 left=right=mid=(status?0:len()); 26 } 27 }st[10*MAX]; 28 struct seg//记录区间 29 { 30 int left,right; 31 }; 32 vector <seg> ve;//储存区间信息 33 seg oh;//临时储存 34 void init(int l,int r,int k) 35 { 36 st[k].al=l; 37 st[k].ar=r; 38 st[k].status=0; 39 st[k].actl(); 40 if(l==r) 41 return; 42 init(l,(l+r)/2,2*k); 43 init((l+r)/2+1,r,2*k+1); 44 } 45 void pushdown(int k) 46 { 47 if(st[k].status!=-1) 48 { 49 st[2*k].status=st[2*k+1].status=st[k].status; 50 st[k].status=-1; 51 st[2*k].actl(); 52 st[2*k+1].actl(); 53 } 54 } 55 int query(int len,int k) 56 { 57 if(len==1&&st[k].al==st[k].ar) 58 return st[k].al; 59 if(st[k].mid<len) 60 return -1; 61 pushdown(k); 62 if(st[2*k].mid>=len) 63 return query(len,2*k); 64 else if(st[2*k].right+st[2*k+1].left>=len) 65 return st[2*k].ar-st[2*k].right+1; 66 else if(st[2*k+1].mid>=len) 67 return query(len,2*k+1); 68 return -1; 69 } 70 void update(int ul,int ur,int l,int r,int k,int val) 71 { 72 if(l==ul&&r==ur) 73 { 74 st[k].status=val; 75 st[k].actl(); 76 return; 77 } 78 if(l==r) 79 return; 80 pushdown(k); 81 int mid=(l+r)/2; 82 if(ur<=mid) 83 update(ul,ur,l,mid,2*k,val); 84 else if(ul>mid) 85 update(ul,ur,mid+1,r,2*k+1,val); 86 else 87 { 88 update(ul,mid,l,mid,2*k,val); 89 update(mid+1,ur,mid+1,r,2*k+1,val); 90 } 91 st[k].mid=max(st[2*k].mid,st[2*k+1].mid); 92 st[k].left=st[2*k].left; 93 st[k].right=st[2*k+1].right; 94 st[k].mid=max(st[2*k].right+st[2*k+1].left,st[k].mid); 95 if(st[2*k].left==st[2*k].len()) 96 st[k].left+=st[2*k+1].left; 97 if(st[2*k+1].right==st[2*k+1].len()) 98 st[k].right+=st[2*k].right; 99 return; 100 } 101 char command[10]; 102 int tem,an; 103 int lo;//添加的位置 104 int binarysearch(int k) 105 { 106 int l,r,mid; 107 l=0;r=ve.size()-1; 108 while(l<=r) 109 { 110 mid=(l+r)/2; 111 if(ve[mid].left<=k) 112 l=mid+1; 113 else if(ve[mid].left>k) 114 r=mid-1; 115 } 116 return l; 117 } 118 int main() 119 { 120 while(~scanf("%d %d",&N,&M)) 121 { 122 ve.clear(); 123 init(1,N,1); 124 while(M--) 125 { 126 scanf("%s",command); 127 if(command[0]==‘R‘) 128 { 129 ve.clear(); 130 st[1].status=0; 131 st[1].actl(); 132 pushdown(1); 133 printf("Reset Now\n"); 134 } 135 else if(command[0]==‘N‘) 136 { 137 scanf("%d",&tem); 138 an=query(tem,1); 139 if(an==-1) 140 printf("Reject New\n"); 141 else 142 { 143 oh.left=an;oh.right=an+tem-1; 144 lo=binarysearch(an); 145 ve.insert(ve.begin()+lo,oh); 146 147 update(an,an+tem-1,1,N,1,1); 148 printf("New at %d\n",an); 149 } 150 } 151 else if(command[0]==‘F‘) 152 { 153 scanf("%d",&tem); 154 lo=binarysearch(tem)-1; 155 if(lo<=-1||ve[lo].right<tem) 156 printf("Reject Free\n"); 157 else 158 { 159 update(ve[lo].left,ve[lo].right,1,N,1,0); 160 printf("Free from %d to %d\n",ve[lo].left,ve[lo].right); 161 ve.erase(ve.begin()+lo,ve.begin()+lo+1);//删除掉ve中的这个seg区间 162 } 163 } 164 else if(command[0]==‘G‘) 165 { 166 scanf("%d",&tem); 167 if(tem>ve.size()) 168 printf("Reject Get\n"); 169 else 170 { 171 printf("Get at %d\n",ve[tem-1].left); 172 } 173 } 174 } 175 printf("\n");//题意要求两组数据之间换行 176 } 177 }
以上是关于(线段树,二分)hdoj 2871-Memory Control的主要内容,如果未能解决你的问题,请参考以下文章