当前位置:编程学习 > C/C++ >>

HDOJ 4288 Coder(线段树)

[cpp] 
/*
线段树很强大,这个应该也属于区间处理、多次查询的问题,所以要用到线段树解决。
sum[]分别表示区间内%5余数之和,cnt表示区间内总个数
首先离散化,然后建立线段树(让线段树中l,r与A[]数组相对应起来),然后添加和删除元素即可
*/ 
 
 
#include <cstdio> 
#include <cstdlib> 
#include <cstring> 
const __int64 nMax = 100007; 
__int64 N; 
struct Node 

    char opr[5]; 
    __int64 a; 
    Node(){} 
    Node(char *_opr, __int64 _a) 
    { 
        memcpy(opr, _opr, sizeof(opr)); 
        a = _a; 
    } 
}node[nMax]; 
struct Tree 

    __int64 l, r; 
    __int64 sum[5]; 
    __int64 cnt; 
}tree[nMax * 4]; 
__int64 A[nMax]; 
__int64 cnt; 
 
int cmp(const void *a, const void *b) 

    __int64 *pa = (__int64 *) a; 
    __int64 *pb = (__int64 *) b; 
    return *pa - *pb; 

 
void build(__int64 rt, __int64 l, __int64 r) 

    if(l < r) 
    { 
        __int64 mid = (l + r) / 2; 
        build(rt * 2, l, mid); 
        build(rt * 2 + 1, mid + 1, r); 
    } 
    tree[rt].l = l; 
    tree[rt].r = r; 
    tree[rt].cnt = 0; 
    memset(tree[rt].sum, 0, sizeof(tree[rt].sum)); 

 
void add(__int64 rt, __int64 a) 

    if(tree[rt].l == tree[rt].r) 
    { 
        tree[rt].cnt = 1; 
        tree[rt].sum[1] = a; 
        return; 
    } 
    __int64 mid = (tree[rt].l + tree[rt].r) / 2; 
    if(a <= A[mid]) 
        add(rt * 2, a); 
    else 
        add(rt * 2 + 1, a); 
    tree[rt].cnt = tree[rt * 2].cnt + tree[rt * 2 + 1].cnt; 
    __int64 i; 
    memset(tree[rt].sum, 0, sizeof(tree[rt].sum)); 
    for(i = 0; i < 5; ++ i) 
    { 
        tree[rt].sum[i] += tree[rt * 2].sum[i]; 
        tree[rt].sum[(tree[rt * 2].cnt + i) % 5] += tree[rt * 2 + 1].sum[i]; 
    } 

 
void del(__int64 rt, __int64 a) 

    if(tree[rt].l == tree[rt].r) 
    { 
        tree[rt].cnt = 0; 
        tree[rt].sum[1] = 0; 
        return; 
    } 
    __int64 mid = (tree[rt].l + tree[rt].r) / 2; 
    if(a <= A[mid]) 
        del(rt * 2, a); 
    else 
        del(rt * 2 + 1, a); 
    tree[rt].cnt = tree[rt * 2].cnt + tree[rt * 2 + 1].cnt; 
    __int64 i; 
    memset(tree[rt].sum, 0, sizeof(tree[rt].sum)); 
    for(i = 0; i < 5; ++ i) 
    { 
        tree[rt].sum[i] += tree[rt * 2].sum[i]; 
        tree[rt].sum[(tree[rt * 2].cnt + i) % 5] += tree[rt * 2 + 1].sum[i]; 
    } 

 
int main() 

    //freopen("e://data.in", "r", stdin) 
    while(scanf("%I64d", &N) != EOF) 
    { 
        __int64 i, j; 
        char opr[5]; 
        __int64 a; 
        cnt = 0; 
        for(i = 0; i < N; ++ i) 
        { 
            scanf("%s", opr); 
            if(opr[0] == 'a') 
            { 
                scanf("%I64d", &a); 
                A[cnt ++] = a; 
            } 
            else if(opr[0] == 'd') 
            { 
                scanf("%I64d", &a); 
            } 
            else a = 0; 
            node[i] = Node(opr, a); 
        } 
        qsort(A, cnt, sizeof(A[0]), cmp); 
        for(i = 1, j = 1; i < cnt; ++ i) 
            if(A[i] != A[i - 1]) 
                A[j ++] = A[i]; 
        cnt = j; www.zzzyk.com
        build(1, 0, cnt - 1); 
        for(i = 0; i < N; ++ i) 
        { 
            if(node[i].opr[0] == 'a') 
                add(1, node[i].a); 
            else if(node[i].opr[0] == 'd') 
                del(1, node[i].a); 
            else 
                printf("%I64
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,