hdu 2871 线段树(各种操作)
Memory Control
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5913 Accepted Submission(s): 1380
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.
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.
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.
- 6 10
- New 2
- New 5
- New 2
- New 2
- Free 3
- Get 1
- Get 2
- Get 3
- Free 3
- Reset
- 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 线段树(各种操作)的更多相关文章
- HDU - 4578 线段树+三重操作
这道题自己写了很久,还是没写出来,也看了很多题解,感觉多数还是看的迷迷糊糊,最后面看到一篇大佬的才感觉恍然大悟. 先上一篇大佬的题解:https://blog.csdn.net/aqa20372995 ...
- hdu 3436 线段树 一顿操作
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- hdu 3974 线段树 将树弄到区间上
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3397 线段树双标记
Sequence operation Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu 4578 线段树(标记处理)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others) ...
- hdu 4267 线段树间隔更新
A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K ...
- hdu 1754 线段树(Max+单点修改)
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- Can you answer these queries? HDU 4027 线段树
Can you answer these queries? HDU 4027 线段树 题意 是说有从1到编号的船,每个船都有自己战斗值,然后我方有一个秘密武器,可以使得从一段编号内的船的战斗值变为原来 ...
- HDU 5634 线段树
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5634 题意:给定一个长度为n的序列,有m次操作.操作有3种: 1 l,r :区间[l,r]的值变成ph ...
随机推荐
- 【iOS】字号问题
一,ps和pt转换 px:相对长度单位.像素(Pixel).(PS字体) pt:绝对长度单位.点(Point).(iOS字体) 公式如下: pt=(px/96)*72. 二,字体间转换 1in = 2 ...
- aix 6.1系统怎么安装?这里有详细图文教程
今年六月,我们公司出现了一次非常严重的数据丢失的事故.生产服务器崩溃导致所有的业务都陷于停滞,而且由于涉及到公司机密又无法贸然到数据恢复公司进行恢复,可是自己又无法解决.权衡利弊还是决定找一家有保密资 ...
- ASCII排序
ASCII码排序 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个字符. 输入 第一行输 ...
- 用java写一个servlet,可以将放在tomcat项目根目录下的文件进行下载
用java写一个servlet,可以将放在tomcat项目根目录下的文件进行下载,将一个完整的项目进行展示,主要有以下几个部分: 1.servlet部分 Export 2.工具类:TxtFileU ...
- python之路--day8---day9--两日内容
一.不使用函数的问题 1,代码的组织结构不清晰,可读性差 2,遇到重复的功能只能重复编写实现代码,代码冗余 3,功能需要扩展时,需要找出所有实现该功能的地方修改,无法统一管理且维护难度极大 二.函数是 ...
- SQL Server 2012 管理新特性:AlwaysOn 可用性组
SQL Server 2012 新特性(一)管理新特性:AlwaysOn 一.准备环境 1.准备4台计算机 域控制器DC1,IP地址192.168.1.1 主节点SQL1:IP地址192.168.1. ...
- 日推20单词 Day02
1.distinguish v. 区别,辨别 2.tension n. 紧张,不安 3.sympathy n. 同情,慰问 4.admiration n. 羡慕 5.jealousy n. 嫉妒 6. ...
- tk mybatis通用mapper,复杂and or条件查询
需求:where查询,需要支持(a or b or c) and d 也就是a.b.c三个条件是或的关系,然后再与d相与. 尝试后,可以通过以下方式处理: 方式1:Weekend语法 Weekend& ...
- sqlalchemy通过ssh连接远程mysql服务器
首先需要一个模块sshtunnel,如果没有直接pip install sshtunnel from sshtunnel import SSHTunnelForwarder from sqlalche ...
- python的错误处理
一.python的错误处理 在程序运行的过程中,如果发生了错误,可以事先约定返回一个错误代码,这样,就可以知道是否有错以及出错的原因. 在操作系统提供的调用中,返回错误码非常常见.比如打开文件的函数o ...