hdu - 1754 I Hate It(線段樹)

本文借鑑博文:

http://blog.csdn.net/panyanyany/article/details/6776300


最基本的線段樹操作(構造,插入更新,查找)

剛開始學線段樹,套一些網上的簡單題模板


題目:

I Hate It


代碼:

數組實現建樹

//#pragma comment(linker, "/STACK:102400000,102400000")
#include "iostream"
#include "cstring"
#include "algorithm"
#include "cmath"
#include "cstdio"
#include "sstream"
#include "queue"
#include "vector"
#include "string"
#include "stack"
#include "cstdlib"
#include "deque"
#include "fstream"
#include "map"
using namespace std;
typedef long long LL;
const int INF = 522133279;
const int MAXN = 1000000+100;
#define eps 1e-14
const int mod = 95041567;

int n,m;
int num[200000+100];        //各學生成績

struct t
{
    int l,r;
    int maxc;
}tree[2000000+100];         //數組法構造二叉數,基本邏輯是:根節點的位置爲i,那麼其兩個子節點的的位置爲2*i,2*i+1

int build(int root , int l , int r)             //構造子線段
{
    int mid;

    tree[root].l=l;
    tree[root].r=r;

    if(l == r)                                  //區間變成點,則區間對應的特性值確定
        return tree[root].maxc = num[l];

    mid = (l+r)/2;                              //否則繼續構造子線段

    return tree[root].maxc = max(build(2*root,l,mid) , build(2*root+1,mid+1,r));
}

int find_max(int root , int l , int r)
{
    if(tree[root].l >r || tree[root].r < l)     //如果目的區間不在當前覆蓋區間,則返回一個不可達最小值
        return 0;

    if(tree[root].r <= r &&tree[root].l >= l)   //如果目的區間包含當前覆蓋區間,則返回當前覆蓋區間的最大值
        return tree[root].maxc;

    return max(find_max(root*2,l,r),find_max(root*2+1,l,r));    //若區間相交,繼續尋找
}

int up(int root , int pos , int v)
{
    if(pos < tree[root].l || pos > tree[root].r)
        return tree[root].maxc;

    if(pos == tree[root].l && pos == tree[root].r)      //找到位置就更新
        return tree[root].maxc = v;

    return tree[root].maxc = max(up(root*2,pos,v),up(root*2+1,pos,v));
}



int main()
{
    //freopen("in","r",stdin);
    //freopen("out","w",stdout);

    while(cin >> n >> m)
    {
        memset(tree,0,sizeof(tree));

        for(int i = 1 ; i <= n ; i++)
            cin >> num[i];
        build(1,1,n);

        for(int i= 0 ; i < m ; i++)
        {
            char c;
            int a,b;
            cin >> c >>a>> b;

            if(c == 'Q')
                cout << find_max(1,a,b) << endl;
            else
            {
                num[a]=b;
                up(1,a,b);
            }
        }
    }

    return 0;
}

指針實現建樹

//#pragma comment(linker, "/STACK:102400000,102400000")
#include "iostream"
#include "cstring"
#include "algorithm"
#include "cmath"
#include "cstdio"
#include "sstream"
#include "queue"
#include "vector"
#include "string"
#include "stack"
#include "cstdlib"
#include "deque"
#include "fstream"
#include "map"
using namespace std;
typedef long long LL;
const int INF = 522133279;
const int MAXN = 1000000+100;
#define eps 1e-14
const int mod = 95041567;

struct node
{
    int l,r;
    node *lc,*rc;
    int maxc;

    node(int _l , int _r):l(_l) , r(_r) , lc(NULL) , rc(NULL)
    {}

}*root;

int num[200000+100];
int n,m;

int build(node **seg , int l , int r)
{
    *seg = new node(l,r);

    if(l == r)
        return (*seg)->maxc = num[l];

    int mid = (l+r)/2;

    return (*seg)->maxc = max(build(&((*seg)->lc) , l , mid) , build(&((*seg)->rc) , mid+1,r));
}

int up(node **seg , int pos , int v)
{
    if((*seg)->l > pos || (*seg)->r < pos)
        return (*seg)->maxc;

    if((*seg)->l == pos && (*seg)->r == pos)
        return (*seg)->maxc = v;

    return (*seg)->maxc = max(up(&((*seg)->lc) , pos , v) , up(&((*seg)->rc) , pos , v));
}

int find_max(node **seg , int l , int r)
{
    if((*seg)->l > r || (*seg)->r < l)
        return 0;

    if((*seg)->r <= r && (*seg)->l >= l)
        return (*seg)->maxc;

    return max(find_max(&((*seg)->lc) , l , r) , find_max(&((*seg)->rc) , l , r));
}

void del(node **seg)
{
    if((*seg) == NULL)
        return;

    del(&((*seg)->lc));
    del(&((*seg)->rc));

    delete *seg;
}


int main()
{
    //freopen("in","r",stdin);
    //freopen("out","w",stdout);

    while(~scanf("%d%d",&n,&m))
    {
        getchar();
        root = NULL;
        for(int i = 1 ; i <= n ; i++)
            scanf("%d",num+i);
        getchar();
        build(&root , 1,n);

        for(int i = 0 ; i < m; i++)
        {
            char c;
            int a,b;
            scanf("%c%d%d",&c,&a,&b);
            getchar();
            if(c == 'Q')
                printf("%d\n",find_max(&root , a , b));
            else
            {
                num[a]=b;
                up(&root,a,b);
            }
        }

        del(&root);
    }

    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章