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;
}