Hdu2871Memory Control线段树

  

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <map>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>
#include<math.h>
#include<vector>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn = 55555;
int color[maxn << 2], sum[maxn << 2], lsum[maxn << 2], rsum[maxn << 2];
struct Node
{
    int a; int b;
};
int a;
vector<Node > q;
void down(int rt, int m)
{
    if (~color[rt]){
        color[rt << 1] = color[rt << 1 | 1] = color[rt];
        sum[rt << 1] = lsum[rt << 1] = rsum[rt << 1] = color[rt] ? 0 : (m - (m >> 1));
        sum[rt << 1 | 1] = lsum[rt << 1 | 1] = rsum[rt << 1 | 1] = color[rt] ? 0 : (m >> 1);
        color[rt] = -1;
    }
}

void up(int rt, int m)
{
    lsum[rt] = lsum[rt << 1];
    rsum[rt] = rsum[rt << 1 | 1];
    if (lsum[rt] == (m - (m >> 1))) lsum[rt] += lsum[rt << 1 | 1];
    if (rsum[rt] == (m >> 1)) rsum[rt] += rsum[rt << 1];
    sum[rt] = max(max(sum[rt << 1], sum[rt << 1 | 1]), rsum[rt << 1] + lsum[rt << 1 | 1]);
}

void build(int l, int r, int rt)
{
    color[rt] = -1;sum[rt]=lsum[rt]=rsum[rt]=r-l+1;
    if(l==r) return ;
    int mid = (l + r) >> 1;
    build(lson);
    build(rson);
}

void update(int L, int R, int add, int l, int r, int rt)
{
    if (L <= l&&r <= R){
        sum[rt] = lsum[rt] = rsum[rt] = add ? 0 : (r - l + 1);
        color[rt] = add;
        return;
    }
    down(rt, r - l + 1);
    int mid = (l + r) >> 1;
    if (L <= mid) update(L, R, add, lson);
    if (R > mid)  update(L, R, add, rson);
    up(rt, r - l + 1);
}

int ask(int key, int l, int r, int rt)
{
    if (l == r) return l;
    down(rt, r - l + 1);
    int mid = (l + r) >> 1;
    if (key <= sum[rt << 1]) return ask(key, lson);
    if (rsum[rt << 1] + lsum[rt << 1 | 1] >= key) return mid - rsum[rt << 1] + 1;
    return ask(key, rson);
}
int erfen(int x)
{
    int l = 0; int r = q.size() - 1;
    while (l <= r){
        int mid = (l + r) >> 1;
        if (q[mid].a > x){
            r = mid - 1;
        }
        else l = mid + 1;
    }
    return l;
}
int  main()
{
    int n, m;
    char str[100];
    while (scanf("%d%d",&n,&m)!=EOF){
        build(1, n, 1);
        q.clear();
        for (int i = 0; i < m; i++){
            scanf("%s", str);
            if (str[0] == ‘R‘){
                update(1,n,0,1,n,1);
                q.clear();printf("Reset Now\n");continue;
            }
            scanf("%d", &a);
            if (str[0] == ‘N‘){
                if(sum[1]<a){
                    printf("Reject New\n");continue;
                }
                int t = ask(a, 1, n, 1);
                int pos = erfen(t);
                Node gg; gg.a = t; gg.b = t + a - 1;
                q.insert(q.begin() + pos, gg);
                update(t, t + a - 1, 1, 1, n, 1);
                printf("New at %d\n", t);
            }
            if (str[0] == ‘F‘){
                int pos = erfen(a)-1;
                if (pos<=-1||q[pos].b < a){
                    printf("Reject Free\n"); continue;
                }
                update(q[pos].a, q[pos].b, 0, 1, n, 1);
                printf("Free from %d to %d\n", q[pos].a, q[pos].b);
                q.erase(q.begin()+pos,q.begin()+pos+1);
            }
            if (str[0] == ‘G‘){
                if (q.size() < a){
                    printf("Reject Get\n"); continue;
                }
                printf("Get at %d\n", q[a-1].a);
            }
        }
        printf("\n");
    }
    return 0;
}

Hdu2871Memory Control线段树,布布扣,bubuko.com

时间: 2024-06-18 00:37:31

Hdu2871Memory Control线段树的相关文章

hdu 2871 Memory Control(线段树)

题目链接:hdu 2871 Memory Control 题目大意:模拟一个内存分配机制. Reset:重置,释放所有空间 New x:申请内存为x的空间,输出左地址 Free x:释放地址x所在的内存块 Get x:查询第x个内存块,输出左地址 解题思路:一开始全用线段树去做,写的乱七八糟,其实只要用线段树维护可用内存.然后用户一个vector记录所有的内存块. #include <cstdio> #include <cstring> #include <vector>

HDU 2871 Memory Control (线段树,区间合并)

http://acm.hdu.edu.cn/showproblem.php?pid=2871 Memory Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4418    Accepted Submission(s): 1056 Problem Description Memory units are numbered

HDU 2871 Memory Control(线段树)

HDU 2871 Memory Control 题目链接 题意:内存操作,和hotel那题差不多,多一个get操作 思路:线段树区间合并,其他都差不多,多一个get操作,这个用set去乱搞就过了- -,估计数据鶸吧,多这个操作感觉要用splay去搞了 代码: #include <cstdio> #include <cstring> #include <algorithm> #include <set> using namespace std; const i

hdu3698 Let the light guide us dp+线段树优化

http://acm.hdu.edu.cn/showproblem.php?pid=3698 Let the light guide us Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 62768/32768 K (Java/Others) Total Submission(s): 821    Accepted Submission(s): 285 Problem Description Plain of despair was

题解 HDU 3698 Let the light guide us Dp + 线段树优化

http://acm.hdu.edu.cn/showproblem.php?pid=3698 Let the light guide us Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 62768/32768 K (Java/Others) Total Submission(s): 759    Accepted Submission(s): 253 Problem Description Plain of despair was

洛谷P2826 [USACO08NOV]光开关Light Switching [2017年6月计划 线段树02]

P2826 [USACO08NOV]光开关Light Switching 题目描述 Farmer John tries to keep the cows sharp by letting them play with intellectual toys. One of the larger toys is the lights in the barn. Each of the N (2 <= N <= 100,000) cow stalls conveniently numbered 1..N

线段树题目总结

一.单点更新 1.hdu1166 敌兵布阵:有N个兵营,每个兵营都给出了人数ai(下标从1开始),有四种命令,(1)"Addij",表示第i个营地增加j人.(2)"Sub i j",表示第i个营地减少j人.(3)"Query ij",查询第i个营地到第j个营地的总人数.(4)"End",表示命令结束.解题报告Here. 2.hdu1754 I Hate It:给你N个数,M个操作,操作分两类.(1)"QAB"

线段树题目汇总

区间合并部分: POJ 3667 Hotel 求某大于等于a的最长区间 #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #define LEN 50001<<2 using namespace std; struct Line_tree { //分别表示以当前区间为左端点的最长连续空白区间,为右端点的最长连续空白区间,该区间的最长连续空白区

数据结构---线段树

线段树 转载请注明出处,谢谢!http://blog.csdn.net/metalseed/article/details/8039326  持续更新中···   一:线段树基本概念 1:概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN)! 性质:父亲的区间是[a,b],(c=(a+b)/2)左儿子的区间是[a,c],右儿子的区间是[c+1,b],线段树