HDU4217 Data Structure(线段树)

来源:互联网 发布:印度神油 知乎 编辑:程序博客网 时间:2024/06/02 04:25

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4217  

题目大意:给n和k,以及k个数(序列ki),表示一个1到n的序列,进行k次操作,每次取出序列中第ki小的数,问经过k次操作后,取出的数的和为多少?

线段树,segTree维护的是rt节点下区间里有多少个数,每次删除时把包含第ki小的数的区间大小都减1。

结果用long long.

#include <iostream>#include <cstdio>#include <fstream>#include <string>#include <deque>#include <vector>#include <algorithm>using namespace std;const int maxn = 270000;int segTree[maxn<<2];void build(int node, int l, int r) {    if(l == r) {        segTree[node] = 1;        return ;    }    int mid = (l + r) >> 1;    build(2 * node, l, mid);    build(2 * node + 1, mid + 1, r); //   segTree[node] = r - l + 1;    segTree[node] = segTree[node<<1] + segTree[node<<1|1];}int del(int node, int l, int r, int x) {    segTree[node] --;    if(l == r) {        return l;    }    int mid = (l + r) >> 1;    if(x <= segTree[node<<1]) {        return del(2*node, l, mid, x);    }    else {        return del(2*node+1, mid + 1, r, x-segTree[node<<1]);    }}int main() {    int t, cas = 1;    int n, k, x;    scanf("%d", &t);    long long sum = 0;    while (t --) {        scanf("%d%d", &n, &k);        build(1, 1, n);        sum = 0;        for(int i = 0; i < k; i ++) {            scanf("%d", &x);            sum += (long long)del(1, 1, n, x);        }        printf("Case %d: %I64d\n", cas ++, sum);    }    return 0;}





0 0
原创粉丝点击