HDU 4217 Data Structure?

简单的线段树

val存当前节点子树的删减后存在的个数

!!!总是忘记算一下int范围够不够  这里要用int64 !!! 要注意相加或相乘很容易溢出啊!!!

则每次若左子树val较小  删除的树就在右子树  具体看代码

View Code
Problem Description
Data structure is one of the basic skills for Computer Science students, which is a particular way of storing and organizing data in a computer so that it can be used efficiently. Today let me introduce a data-structure-like problem for you.
Original, there are N numbers, namely 1, 2, 3...N. Each round, iSea find out the Ki-th smallest number and take it away, your task is reporting him the total sum of the numbers he has taken away.
 

Input
The first line contains a single integer T, indicating the number of test cases.
Each test case includes two integers N, K, K indicates the round numbers. Then a line with K numbers following, indicating in i (1-based) round, iSea take away the Ki-th smallest away.

Technical Specification
1. 1 <= T <= 128
2. 1 <= K <= N <= 262 144
3. 1 <= Ki <= N - i + 1
 

Output
For each test case, output the case number first, then the sum.
 

Sample Input
2
3 2
1 1
10 3
3 9 1
 

Sample Output
Case 1: 3
Case 2: 14
#include <stdio.h>
#include <string.h>
#include <algorithm>

#define MAXN 300006
int n;
struct Node
{
    int val, ld, rd;
}t[MAXN<<2];
void build(int pos, int st, int ed)
{
    t[pos].val = ed-st+1 ;
    t[pos].ld = st, t[pos].rd = ed;
    if(st == ed)
        return ;
    int mid = (st+ed)/2 ;
    build(pos*2, st, mid);
    build(pos*2+1, mid+1, ed);
}

int update(int pos, int key)
{
    t[pos].val --;   //因为key一定在当前节点的子树里 所以删除后当前节点的val要减1
    if(t[pos].ld == t[pos].rd)
        return t[pos].ld;
    if(t[pos*2].val >= key)
        return    update(pos*2, key);
    else
        return update(pos*2+1, key-t[pos*2].val);   //key若在右子树 要减去左子树的val
}

int main()
{
    int i, k, cas, nCase = 0, a;
    scanf("%d", &cas);
    while(cas--)
    {
        __int64 ans = 0;
        scanf("%d %d", &n, &k);    
        build(1, 1, n);
        while(k--)
        {
            scanf("%d", &a);
            ans += update(1, a);
        }
        printf("Case %d: %I64d\n", ++nCase, ans);
    }
    return 0;
}

 

posted @ 2013-05-08 13:49  April_Tsui  阅读(145)  评论(0编辑  收藏  举报