hdu 2871 -Memory Control--线段树

本文探讨了一位开发者在解决内存控制问题时遇到的挑战,并通过使用线段树来优化代码效率的过程。重点阐述了如何识别并修复错误逻辑,以及线段树在复杂操作中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我去此题我简直不想喷了,三个小时没检查出ql和qr弄反了。我简直受不了啊

//
//  main.cpp
//  hdu 2871 -Memory Control--线段树
//
//  Created by XD on 15/9/13.
//  Copyright (c) 2015年 XD. All rights reserved.
#include <iostream>
#include <queue>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<vector>
#include <string.h>
#include <algorithm>
#include <set>
#include <map>
#include <cstdio>
#define ll long long
using namespace std ;
const int maxn = 50000*6 +10  ;
int ans ;
struct IntervalTree{
    int _set[maxn] , _pre[maxn] , _suffix[maxn],_sum[maxn] ;
    int ql ,qr , q,v,d;
    void init()
    {
        memset(_set, -1, sizeof(_set)) ;
        memset(_sum, 0, sizeof(_sum)) ;
    }
    void build(int o , int L , int R)
    {
        int lc = o *2 ; int rc = o *2 + 1 ;
        int m =  L + (R - L ) /2 ;
        if(L  < R )
        {
            _pre[o] = _suffix[o] = R - L + 1 ;
            build(lc, L  , m ) ;
            build(rc, m+1, R) ;
        }
        else{
            _suffix[o] = _pre[o] = 1 ;
        }
    }
    void pushdown(int o)
    {
        if(_set[o]>=0 )
        {
            _set[o*2] = _set[o*2+1] =_set[o] ;
            _set[o] = -1;
        }
    }
    void maintain(int o, int L ,int R)
    {
        int lc = o *2 ; int rc = o *2 +1 ;
        if(L < R )
        {
            int m = L + (R-L)/2 ;
            _sum[o] = _sum[lc] + _sum[rc] ;
            _pre[o] = _pre[lc] == m - L +1 ?_pre[lc] + _pre[rc] : _pre[lc] ;
            _suffix[o] = _suffix[rc] == R - m ? _suffix[lc] + _suffix[rc]:_suffix[rc] ;
        }
        if(_set[o] == 0 )
        {
            _sum[o] = 0 ;
            _suffix[o] = _pre[o] = R - L +1 ;
        }
        else if (_set[o] == 1 )
        {
            _sum[o] = R -L+1 ;
            _suffix[o] = _pre[o] = 0 ;
        }
    }
    void update(int o , int L ,int R)
    {
        int rc = o *2+1  ;int lc = o *2  ;
        if(ql <= L && qr >= R)
        {
            _set[o] = v  ;
        }
        else{
            pushdown(o)  ;
            int m = L + (R-L)/2 ;
            if(ql <= m ) update(lc, L  , m) ; else maintain(lc , L , m) ;
            if(qr > m ) update(rc,  m+1 , R) ; else maintain(rc, m+1, R) ;
        }
        maintain(o , L, R) ;
    }
    void getstart(int o , int  L ,int R)
    {
        if(R - L +1 <d || R - L + 1 - _sum[o] < d)
        {
            return ;
        }
        
        if(_sum[o]==0)
        {
            ans =  L ;
            return ;
        }
        int m =  L + (R -L) /2  ;
        int lc =  o*2 ; int rc = o*2 + 1 ;
        getstart(lc, L  , m) ;
        if(ans >  0 ) return ;
        if(_suffix[lc] + _pre[rc] >= d)
        {
            if(_suffix[lc] > 0 ) ans = m - _suffix[lc] +1 ;
            else ans = m+1 ;
            return ;
        }
        getstart(rc, m+1, R) ;
    }
};
IntervalTree tree ;
struct block
{
    int begin ,end ;
    block(int begin ,int end):begin(begin) ,end(end){} ;

    block(){} ;
    bool operator < (const block &n ) const{
        return  begin < n.begin ;
    } ;
};
vector<block> v ;
int main(int argc, const char * argv[]) {
    int  n , m,x,pos;
    char cmd[10] ;vector<block>::iterator it  ;
    while (scanf("%d%d" , &n,&m)==2&&n&&m) {
        v.clear() ;
        v.push_back(block(500001,0)) ;
        tree.init() ;
        tree.build(1, 1, n) ;
        for (int i = 0; i < m; i++) {
            scanf("%s" ,cmd) ;
            switch (cmd[0]) {
                case 'R':
                    tree.v = 0 ;
                    //一开始写成了ql = n , qr = 1 ,囧竟然3个小时没发现,我了个去
                    tree.ql= 1 ;tree.qr = n ;
                    tree.update(1, 1, n) ;
                    v.clear() ;
                    v.push_back(block(500001,0)) ;
                    printf("Reset Now\n") ;
                    break;
                case 'N':
                    scanf("%d" , &tree.d) ;
                    ans = 0 ;
                    tree.getstart(1, 1, n) ;
                    if(ans==0)
                    {printf("Reject New\n") ;break;}
                    it = upper_bound(v.begin() ,v.end() , block(ans ,0))  ;
                    v.insert(it, block(ans , ans + tree.d -1 )) ;
                    tree.v = 1 ;
                    tree.ql = ans ; tree.qr =ans  +tree.d -1  ;
                    tree.update(1, 1, n) ;
                    printf("New at %d\n" , ans) ;
                    break  ;
                case 'G':
                    scanf("%d" , &x) ;
//                    l  =getStart(x , n ) ;
                    if ( x<= v.size()-1)  {
                        printf("Get at %d\n" , v[x-1].begin) ;
                    }
                    else{
                        printf("Reject Get\n") ;
                    }
                    break ;
                case 'F':
                    scanf("%d" , &x) ;
//                    l = getStart(sum(x),n)  ;
                    it = upper_bound(v.begin() ,v.end() , block(x , 0)) ;
                    pos =(int)( it - v.begin() -1 );
                    if(pos == -1 || v[pos].end<x)
                    {
                        printf("Reject Free\n") ;
                    }
                    else{
                        printf("Free from %d to %d\n" , v[pos].begin, v[pos].end) ;
                        tree.v = 0 ; tree.ql = v[pos].begin ; tree.qr = v[pos].end;
                        tree.update(1, 1, n)  ;
                        v.erase(--it) ;
                    }
            }
        }
        cout<<endl ;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值