• HDU 2871 Memory Control


    HDU_2871

        胡浩的博客上说这个可以做splay的热身题,结果写出来洋洋洒洒270行代码却落得TLE收场,不得不改成线段树去写了。

        reset操作是最简单的,直接将根初始化并加个延迟标记即可。

        我们可以用lc[](left contiguous)表示一个区间从左边开始连续有多少个空位,rc[](right contiguous)表示一个区间从右边开始连续有多少个空位,mc(max contiguous)表示这个区间内最长的连续的空位。有了这三个数组我们就可以很方便地实现New操作了。

        对于Free操作,知道这个点是否是空位是很简单的,但为了获得Memory unit的左、右端点,我们可以额外加两个数组lu[](left unit)、ru[right unit]表示左右端点。这样Free操作的查询功能就实现了,而实现Free删除的功能就可以选择直接对将该段进行染色,染成0即可。

        对于Get操作,我们再额外加一个数组tree[]表示当前这个区间一共有多少个Memory units,但是我们只将每个Memory units左端的unit的tree[]值赋为1,这样就实现了计数的功能,同时查找起来也比较方便,找到的最后一个位置就是该Memory units的左端点。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 50010
    int N, M, tree[4 * MAXD], to[4 * MAXD], mc[4 * MAXD], lc[4 * MAXD], rc[4 * MAXD], lu[4 * MAXD], ru[4 * MAXD];
    int getmax(int x, int y)
    {
    return x > y ? x : y;
    }
    void update(int cur, int x, int y)
    {
    int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
    mc[cur] = getmax(mc[ls], mc[rs]);
    mc[cur] = getmax(mc[cur], rc[ls] + lc[rs]);
    lc[cur] = lc[ls] + (lc[ls] == mid - x + 1 ? lc[rs] : 0);
    rc[cur] = rc[rs] + (rc[rs] == y - mid ? rc[ls] : 0);
    tree[cur] = tree[ls] + tree[rs];
    }
    void pushdown(int cur, int x, int y)
    {
    if(to[cur] != -1)
    {
    int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
    to[ls] = to[rs] = to[cur];
    tree[ls] = tree[rs] = 0;
    mc[ls] = lc[ls] = rc[ls] = (to[cur] ? 0 : mid - x + 1);
    mc[rs] = lc[rs] = rc[rs] = (to[cur] ? 0 : y - mid);
    if(to[cur])
    lu[ls] = lu[rs] = lu[cur], ru[ls] = ru[rs] = ru[cur];
    to[cur] = -1;
    }
    }
    void build(int cur, int x, int y)
    {
    int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
    to[cur] = -1, tree[cur] = 0;
    mc[cur] = lc[cur] = rc[cur] = y - x + 1;
    if(x == y)
    return ;
    build(ls, x, mid);
    build(rs, mid + 1, y);
    }
    int Searchlen(int cur, int x, int y, int len)
    {
    int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
    if(x == y)
    return x;
    pushdown(cur, x, y);
    if(mc[ls] >= len)
    return Searchlen(ls, x, mid, len);
    else if(rc[ls] + lc[rs] >= len)
    return mid - rc[ls] + 1;
    else
    return Searchlen(rs, mid + 1, y, len);
    }
    void color(int cur, int x, int y, int s, int t, int c)
    {
    int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
    if(x >= s && y <= t)
    {
    to[cur] = c;
    tree[cur] = 0;
    mc[cur] = lc[cur] = rc[cur] = (c ? 0 : y - x + 1);
    if(c)
    {
    lu[cur] = s, ru[cur] = t;
    if(x == s)
    {
    if(x != y)
    {
    pushdown(cur, x, y);
    color(ls, x, mid, s, t, c);
    update(cur, x, y);
    }
    else
    tree[cur] = 1;
    }
    }
    return ;
    }
    pushdown(cur, x, y);
    if(mid >= s)
    color(ls, x, mid, s, t, c);
    if(mid + 1 <= t)
    color(rs, mid + 1, y, s, t, c);
    update(cur, x, y);
    }
    int Search(int cur, int x, int y, int goal, int &l, int &r)
    {
    int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
    if(x == y)
    {
    if(mc[cur] == 0)
    {
    l = lu[cur], r = ru[cur];
    return 1;
    }
    return 0;
    }
    pushdown(cur, x, y);
    if(goal <= mid)
    return Search(ls, x, mid, goal, l, r);
    else
    return Search(rs, mid + 1, y, goal, l, r);
    }
    void reset()
    {
    to[1] = tree[1] = 0;
    mc[1] = lc[1] = rc[1] = N;
    printf("Reset Now\n");
    }
    void newunit(int len)
    {
    int x;
    x = Searchlen(1, 1, N, len);
    printf("New at %d\n", x);
    color(1, 1, N, x, x + len - 1, 1);
    }
    void free(int x)
    {
    int l, r;
    if(Search(1, 1, N, x, l, r))
    {
    printf("Free from %d to %d\n", l, r);
    color(1, 1, N, l, r, 0);
    }
    else
    printf("Reject Free\n");
    }
    int getunit(int cur, int x, int y, int k)
    {
    int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
    if(x == y)
    return lu[cur];
    pushdown(cur, x, y);
    if(k <= tree[ls])
    return getunit(ls, x, mid, k);
    else
    return getunit(rs, mid + 1, y, k - tree[ls]);
    }
    void solve()
    {
    int i, j, k, x;
    char b[10];
    for(i = 0; i < M; i ++)
    {
    scanf("%s", b);
    if(b[0] == 'R')
    reset();
    else if(b[0] == 'N')
    {
    scanf("%d", &x);
    if(mc[1] < x)
    printf("Reject New\n");
    else
    newunit(x);
    }
    else if(b[0] == 'F')
    {
    scanf("%d", &x);
    free(x);
    }
    else
    {
    scanf("%d", &k);
    if(tree[1] < k)
    printf("Reject Get\n");
    else
    printf("Get at %d\n", getunit(1, 1, N, k));
    }
    }
    }
    int main()
    {
    while(scanf("%d%d", &N, &M) == 2)
    {
    build(1, 1, N);
    solve();
    printf("\n");
    }
    return 0;
    }


  • 相关阅读:
    Spring Boot属性配置文件详解
    Spring Boot中使用@Scheduled创建定时任务
    Spring Boot中使用@Async实现异步调用
    Spring boot中使用log4j记录日志
    Spring Boot中对log4j进行多环境不同日志级别的控制
    Spring Boot中使用AOP统一处理Web请求日志
    在Windows下安装MongoDB
    MongoDB中的基础概念:Databases、Collections、Documents
    Spring Boot中使用log4j实现http请求日志入mongodb
    Spring Boot中的事务管理
  • 原文地址:https://www.cnblogs.com/staginner/p/2426271.html
Copyright © 2020-2023  润新知