Data Structure? HDU - 4217(线段树)

Data Structure? HDU - 4217

 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

题意:

n个数,1到n,取k次数,每次拿走第ki小的数,输出拿走的k个数的和

思路:

使用线段树,区间维护没有去走的数的个数,每个数用01标记,父节点记录个数。先判断左区间的个数是否大于等于k如果是那么直接在左区间找,当找到l=r相等时即找到了这个点,标记为0,更新父节点,相反如果大于左区间的个数,那么应该在右区间找,那么在右区间中应该找第(k-左区间个数)小的数,因为除去左边的个数了嘛,然后更新方法和左区间相同。

code:

#include <bits/stdc++.h>
using namespace std;
#define lson rt << 1
#define rson rt << 1 | 1
#define MAXN 262150
typedef long long ll;
struct node{
    int l,r,sum;
}tre[MAXN<<2];
ll ans;
void pushup(int rt){
    tre[rt].sum = tre[lson].sum + tre[rson].sum;
}
void build(int rt,int l,int r){
    tre[rt].l = l;
    tre[rt].r = r;
    if(l == r){
        tre[rt].sum = 1;
        return;
    }
    int mid = l + r >> 1;
    build(lson,l,mid);
    build(rson,mid+1,r);
    pushup(rt);
}
void update(int rt,int k){
    if(tre[rt].l == tre[rt].r){
        tre[rt].sum = 0;
        ans += tre[rt].l;
        return;
    }
    if(tre[lson].sum >= k) update(lson,k);
    else update(rson,k-tre[lson].sum);
    pushup(rt);
}
int main(){
    int T,cas = 0;
    scanf("%d",&T);
    while(T--){
        int n,m;
        scanf("%d%d",&n,&m);
        build(1,1,n);
        ans = 0;
        while(m--){
            int k;
            scanf("%d",&k);
            update(1,k);
        }
        printf("Case %d: %lld\n",++cas,ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/codeswarrior/article/details/81111837