1.内存控制
2.敌兵布阵
4.广告牌
5.区间第k大数(模板题)
6.just a Hook
7.I Hate It
8.动态的最长递增子序列(区间更新题)
9.图灵树
10.覆盖的面积
14.买票问题
16.村庄问题
17.Hotel
19.矩形周长问题
23.区间第k大数问题
26.海报问题
1001
1 /* 2 3 内存控制 4 4种操作: 5 1.Reset 初始化 6 2.New x 开辟长度为x的连续的空间,输出起始位置 7 3.Free x 释放包含第x字节的块,整块都释放掉 8 4.Get x 输出当前状态下,内存里第x块的起始位置 9 10 思路: 11 1.Reset 很简单,update(1,N,EMPTY,1);就可以了 12 没有必要重新构树 13 14 2.New x 对于这个操作,和Hotel这道题是一样的。 15 建立树的过程中保存了lmax,rmax,max。在查询的 16 过程中有一些小的技巧。 17 18 3.Free x 释放内存,开一个容器,维护这个容器的顺序。 19 学到了很多容器的知识。海,以前没有学过容器 20 还是学别人的。 21 4.Get x 也是通过维护这个容器,来得到的。 22 23 详细的见代码 24 25 26 */ 27 28 #include<cstdio> 29 #include<iostream> 30 #include<cstdlib> 31 #include<algorithm> 32 #include<vector> 33 #define EMPTY 2 //纯色 此题中代表 空的。 34 #define HH 1 //混色 此题中代表 被占用了。 35 using namespace std; 36 37 38 39 struct node 40 { 41 int l; 42 int r; 43 int lmax,rmax,max; 44 int len; 45 int color; 46 }f[50003*4]; 47 struct st 48 { 49 int begin; 50 int end; 51 }; 52 vector<st>tom; 53 54 55 int hmax(int x,int y) 56 { 57 return x>y? x:y; 58 } 59 60 bool cmp1(st n1,st n2) 61 { 62 return n1.begin<n2.begin; 63 } 64 65 void build(int l,int r,int n) //建树。 66 { 67 int mid=(l+r)/2; 68 f[n].l=l; 69 f[n].r=r; 70 f[n].color=0; 71 f[n].len=f[n].r-f[n].l+1; 72 f[n].lmax=f[n].rmax=f[n].max=f[n].len; 73 if(l==r) 74 return; 75 build(l,mid,n*2); 76 build(mid+1,r,n*2+1); 77 } 78 /* 79 建设的过程也有一个小小的亮点,可以把 80 f[n].lmax=f[n].rmax=f[n].max=f[n].len; 81 用向上更新来写在build(mid+1,r,n*2+1)后,带上 82 */ 83 84 void make_down(int n) //向下更新 85 { 86 if(f[n].color==EMPTY) 87 { 88 f[n*2].max=f[n*2].rmax=f[n*2].lmax=f[n*2].len; 89 f[n*2+1].max=f[n*2+1].rmax=f[n*2+1].lmax=f[n*2+1].len; 90 } 91 else if(f[n].color==HH) 92 { 93 f[n*2].max=f[n*2].lmax=f[n*2].rmax=0; 94 f[n*2+1].max=f[n*2+1].lmax=f[n*2+1].rmax=0; 95 } 96 97 f[n*2].color=f[n].color; 98 f[n*2+1].color=f[n].color; 99 100 f[n].color=0; 101 f[n].lmax=f[n].rmax=f[n].max=0; 102 103 } 104 105 void make_up(node *father,node *l_child,node *r_child) //向上更新 106 { 107 father->lmax=(l_child->lmax==l_child->len)? l_child->lmax+r_child->lmax: l_child->lmax; 108 father->rmax=(r_child->rmax==r_child->len)? r_child->rmax+l_child->rmax: r_child->rmax; 109 father->max=hmax(hmax(father->lmax,father->rmax), 110 hmax(l_child->max, 111 hmax(r_child->max,l_child->rmax+r_child->lmax))); 112 } 113 //为什么这道题,有个小小的亮点,没有rnum ,lnum; 114 //仔细一想确实是不需要的.. 115 116 117 118 void update(int l,int r,int num,int n) //更新函数 区间[l,r],更新为num。 119 { 120 int mid=(f[n].l+f[n].r)/2; 121 if(f[n].l==l && f[n].r==r) 122 { 123 if(num==EMPTY) 124 { 125 f[n].lmax=f[n].rmax=f[n].max=f[n].len; 126 } 127 else f[n].lmax=f[n].rmax=f[n].max=0; 128 f[n].color=num; 129 return; 130 } 131 132 if(f[n].color!=0) 133 make_down(n); 134 if(mid>=r) 135 update(l,r,num,n*2); 136 else if(mid<l) 137 update(l,r,num,n*2+1); 138 else 139 { 140 update(l,mid,num,n*2); 141 update(mid+1,r,num,n*2+1); 142 } 143 make_up(&f[n],&f[n*2],&f[n*2+1]); 144 } 145 146 int query(int max,int n) 147 { 148 int cur=0; 149 150 if(f[n].l==f[n].r) 151 return f[n].l; 152 if(f[n].color!=0) //刚开始,这个别丢了,居然Running time error。 153 make_down(n); 154 155 if(f[n*2].max>=max) 156 cur=query(max,n*2); 157 158 else if(f[n*2].rmax+f[n*2+1].lmax>=max) 159 return f[n*2].r-f[n*2].rmax+1; 160 161 else if(f[n*2+1].max>=max) 162 cur=query(max,n*2+1); 163 164 make_up(&f[n],&f[n*2],&f[n*2+1]); 165 return cur; 166 } 167 /* 168 刚开始 左子树, 169 然后是 左子树右边最大值+右子树左边最大值 170 最后才是 右子树 171 */ 172 173 void make_ini(int N,int M) 174 { 175 char a[10]; 176 int x,l,r,tmp; 177 st hxl; 178 while(M--) 179 { 180 scanf("%s",a); 181 if(a[0]=='R') 182 { 183 update(1,N,EMPTY,1); 184 tom.clear(); 185 printf("Reset Now\n"); 186 } 187 if(a[0]=='N') 188 { 189 scanf("%d",&x); 190 if(f[1].max<x) 191 { 192 printf("Reject New\n"); 193 } 194 else 195 { 196 l=query(x,1); 197 r=l+x-1; 198 hxl.begin=l; 199 hxl.end=r; 200 vector<st>::iterator it; 201 it=upper_bound(tom.begin(),tom.end(),hxl,cmp1);//二分查找,前提是有序。 202 tom.insert(it,hxl); 203 printf("New at %d\n",l); 204 update(l,r,HH,1); 205 } 206 } 207 else if(a[0]=='F') 208 { 209 scanf("%d",&x); 210 hxl.begin=x; 211 hxl.end=x; 212 vector<st>::iterator it;//容器的使用啊 213 it=upper_bound(tom.begin(),tom.end(),hxl,cmp1); 214 215 tmp=it-tom.begin()-1; 216 if(tmp==-1 || tom[tmp].end<x) 217 printf("Reject Free\n"); 218 else 219 { 220 printf("Free from %d to %d\n",tom[tmp].begin,tom[tmp].end); 221 update(tom[tmp].begin,tom[tmp].end,EMPTY,1); 222 tom.erase(tom.begin()+tmp); 223 } 224 } 225 else if(a[0]=='G') 226 { 227 scanf("%d",&x); 228 if(x>tom.size()) 229 printf("Reject Get\n"); 230 else 231 printf("Get at %d\n",tom[x-1].begin);//容器的下标也是从0开始,所以要减1 232 } 233 } 234 } 235 236 int main() 237 { 238 int N,M; 239 while(scanf("%d%d",&N,&M)>0) 240 { 241 tom.clear();//这个必须要的。 242 build(1,N,1); 243 make_ini(N,M); 244 printf("\n"); //!! 245 } 246 return 0; 247 }