Memory Control

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5913    Accepted Submission(s): 1380

Problem Description
Memory units are numbered from 1 up to N.
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. 
 
Input
Input 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.
 
Output
For 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
/*
hdu 2871 线段树(各种操作) New x:从1开始找到一个长度x空白区间来分配内存
Free x:释放x所在连续区间的内存 并输出左右端点
Get x:获得第x个区间的左端点
reset:释放全部的内存 如果对一个区间分配了内存则置为1,空白处全是0
1.对于New操作需要的便是0的最大连续长度 可通过ls,rs,ms来求,先判断区间是否能放下
能则找出它的左端点即可
2.然后是Free,即1的区间。我们可以用from,to来记录一个区间的左右端点,然后通过
push_down下放到单点.所以只需要找出x点对应的节点编号i即可
3.因为求的是第x个区间,所以开始用num求的时候错了好几次。发现可以把区间左端点
标记为1.但是在实现的时候忘记了判断当前位置是否是要更新区间的左端点,卒!
if(tree[i].l == l)
tree[i].num = 1;
4.对于reset,把区间全部更新为0即可 求单点所在区间左右端点+最长连续区间的运用+求第k个区间 hhh-2016-04-02 17:48:33
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <functional>
using namespace std;
#define lson (i<<1)
#define rson ((i<<1)|1)
typedef long long ll;
const int maxn = 50050; struct node
{
int l,r;
int ls,ms,rs; //记录0的连续区间
int num,same;
int from,to; //记录1的左右端点
int mid()
{
return (l+r)>>1;
}
int len()
{
return (r-l+1);
}
} tree[maxn<<2]; void push_up(int i)
{
tree[i].ls = tree[lson].ls,tree[i].rs= tree[rson].rs;
if(tree[i].ls == tree[lson].len())
tree[i].ls += tree[rson].ls;
if(tree[i].rs == tree[rson].len())
tree[i].rs += tree[lson].rs;
tree[i].ms = max(tree[lson].ms,tree[rson].ms);
tree[i].ms = max(tree[i].ms,tree[lson].rs + tree[rson].ls); tree[i].num = tree[lson].num + tree[rson].num;
} void ini(int i,int val)
{
tree[i].ls=tree[i].rs=tree[i].ms=val;
} void build(int i,int l,int r)
{
tree[i].l = l,tree[i].r = r;
tree[i].same =tree[i].from = tree[i].to = -1;
tree[i].num = 0;
if(l == r)
{
ini(i,1);
return ;
}
int mid = (l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
push_up(i);
} void push_down(int i)
{
if(tree[i].same != -1)
{
tree[lson].same = tree[i].same;
tree[rson].same = tree[i].same;
tree[lson].from = tree[rson].from = tree[i].from;
if(tree[i].num != -1)
{
tree[lson].num = tree[i].num;
tree[rson].num = 0;
}
tree[lson].to = tree[rson].to = tree[i].to;
ini(lson,(!tree[i].same)*tree[lson].len());
ini(rson,(!tree[i].same)*tree[rson].len());
tree[i].same = -1;
} } void update(int i,int l,int r,int val)
{
if(tree[i].l >= l && tree[i].r <= r)
{
tree[i].same = val;
if(val)
{
if(tree[i].l == l)
tree[i].num = 1;
tree[i].from = l;
tree[i].to = r;
ini(i,0);
}
else
{
if(tree[i].l == l)
tree[i].num = 0;
tree[i].from = tree[i].to = -1;
ini(i,tree[i].len());
}
return ;
}
push_down(i);
int mid = tree[i].mid();
if(l <= mid)
update(lson,l,r,val);
if(r > mid)
update(rson,l,r,val);
push_up(i);
return ;
} int New(int i,int len)
{
if(tree[i].l == tree[i].r)
{
return tree[i].l;
}
int mid = tree[i].mid();
push_down(i);
if(tree[lson].ms >= len)
return New(lson,len);
else if(tree[lson].rs + tree[rson].ls >= len)
return mid-tree[lson].rs+1;
else
return New(rson,len);
} int Free(int i,int k)
{
if(tree[i].l == tree[i].r)
return i;
push_down(i);
int mid = tree[i].mid();
if(k <= mid)
return Free(lson,k);
else
return Free(rson,k);
} int Get(int i,int k)
{
if(tree[i].l == tree[i].r)
return tree[i].l;
push_down(i);
if(tree[lson].num >= k)
return Get(lson,k);
else
return Get(rson,k-tree[lson].num);
} char op[10]; int main()
{
int n,m;
while(scanf("%d%d",&n,&m) != EOF)
{
build(1,1,n);
int x;
while(m--)
{
scanf("%s",op);
if(op[0] == 'N')
{
scanf("%d",&x); if(tree[1].ms >= x)
{
int l = New(1,x);
printf("New at %d\n",l);
update(1,l,l+x-1,1);
}
else
printf("Reject New\n"); }
else if(op[0] == 'F')
{
scanf("%d",&x);
int t = Free(1,x);
if(tree[t].from == -1)
printf("Reject Free\n");
else
{
printf("Free from %d to %d\n",tree[t].from,tree[t].to);
update(1,tree[t].from,tree[t].to,0);
}
}
else if(op[0] == 'G')
{
scanf("%d",&x);
if(tree[1].num >= x)
printf("Get at %d\n",Get(1,x));
else
printf("Reject Get\n");
}
else if(op[0] == 'R')
{
update(1,1,n,0);
printf("Reset Now\n");
}
}
printf("\n");
}
return 0;
}

  

hdu 2871 线段树(各种操作)的更多相关文章

  1. HDU - 4578 线段树+三重操作

    这道题自己写了很久,还是没写出来,也看了很多题解,感觉多数还是看的迷迷糊糊,最后面看到一篇大佬的才感觉恍然大悟. 先上一篇大佬的题解:https://blog.csdn.net/aqa20372995 ...

  2. hdu 3436 线段树 一顿操作

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  3. hdu 3974 线段树 将树弄到区间上

    Assign the task Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. hdu 3397 线段树双标记

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  5. hdu 4578 线段树(标记处理)

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others) ...

  6. hdu 4267 线段树间隔更新

    A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  7. hdu 1754 线段树(Max+单点修改)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  8. Can you answer these queries? HDU 4027 线段树

    Can you answer these queries? HDU 4027 线段树 题意 是说有从1到编号的船,每个船都有自己战斗值,然后我方有一个秘密武器,可以使得从一段编号内的船的战斗值变为原来 ...

  9. HDU 5634 线段树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5634 题意:给定一个长度为n的序列,有m次操作.操作有3种: 1 l,r :区间[l,r]的值变成ph ...

随机推荐

  1. 团队作业4——第一次项目冲刺(Alpha版本)11.14

    a. 提供当天站立式会议照片一张 举行站立式会议,讨论项目安排: PM对整个项目的需求进行讲解: 全队对整个项目的细节进行沟通: 对整个项目的开发计划进行分析,分配每天的任务: 统一确定项目的开发环境 ...

  2. NOIP2017 列队

    https://www.luogu.org/problemnew/show/P3960 p<=500 50分 模拟 每个人的出队只会影响当前行和最后一列 p<=500,有用的行只有500行 ...

  3. 【技巧】Java工程中的Debug信息分级输出接口及部署模式

    也许本文的标题你们没咋看懂.但是,本文将带大家领略输出调试的威力. 灵感来源 说到灵感,其实是源于笔者在修复服务器的ssh故障时的一个发现. 这个学期初,同袍(容我来一波广告产品页面,同袍官网)原服务 ...

  4. php实现单,双向链表,环形链表解决约瑟夫问题

    传智播客PHP学院 韩顺平 PHP程序员玩转算法第一季  http://php.itcast.cn 聊天篇: 数学对我们编程来说,重不重要? 看你站在什么样的层次来说. 如果你应用程序开发,对数学要求 ...

  5. python构造一个freebuf新闻发送脚本

    前言: 放假学习完web漏洞后.想写一个脚本 然而自己菜无法像大佬们一样写出牛逼的东西 尝试写了,都以失败告终. 还有一个原因:上学时间不能及时看到,自己也比较懒.邮件能提醒自己. 需要安装的模块: ...

  6. Full-Stack-Fundation-Udacity------Lesson 1 Working with CRUD

    因为手头在做一个项目,我负责后台,就顺带快进学习Udacity上一个水课(?):Full Stack Foundation.上课的好像是个印度小哥(?),按1.5倍速听讲话还是有点逗的.废话不多说,进 ...

  7. 关于 Form 表单的 enctype 属性

    enctype 属性一共有3个值 application/x-www-form-urlencoded 在发送前编码所有字符(默认) multipart/form-data 上传二进制数据, 所以在使用 ...

  8. ELK学习总结(3-3)elk的组合查询

    1.bool 查询: must: 必须 should:  可以满足,也可以不满足. must_not: minimum_should_match: 至少要x个匹配才算匹配成功 disable_coor ...

  9. spring-oauth-server实践:授权方式四:client_credentials 模式下access_token的产生

    授权结果 获取access_token成功, 访问资源服务器API http://localhost:9000/api-gateway-engine/unity/user_info?access_to ...

  10. 【52ABP实战教程】0.3-- 从github推送代码回vsts实现双向同步

    需求 在之前的文章中"[DevOps]如何用VSTS持续集成到Github仓库" 我们有讲述如何将vsts中的代码编译推送到github中,这一篇我们来完善,如果有人给你开源项目推 ...