Data Structure?
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3612 Accepted Submission(s): 1177
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
Author
iSea@WHU
Source
题意:n个数,1到n,取k次数,每次拿走第ki小的数,输出拿的k个数的总和
思路:线段树,区间里维护的是还没有取得数的个数,取第k小的数,先判断左区间的数的个数是否不比k小,如果不比k小,则第k小的数肯定在左区间里,查询左区间,否则在右区间里查询第 k-左区间的数的个数 小的数
#include <stdio.h>
#define lson num << 1
#define rson num << 1 | 1
#define MAXN 262150
typedef long long ll;
struct node
{
int l,r;
int sum;
}tree[MAXN << 2];
ll ans;
void pushup(int num)
{
tree[num].sum = tree[lson].sum + tree[rson].sum;
}
void build(int num,int l,int r)
{
tree[num].l = l;
tree[num].r = r;
if(l == r) {
tree[num].sum = 1;
return;
}
int mid = (l + r) >> 1;
build(lson,l,mid);
build(rson,mid + 1,r);
pushup(num);
}
void update(int num,int val)
{
if(tree[num].l == tree[num].r) {
tree[num].sum = 0;
ans += tree[num].l;
return;
}
if(tree[lson].sum >= val) update(lson,val);
else update(rson,val - tree[lson].sum);
pushup(num);
}
int main(void)
{
int T;
scanf("%d",&T);
int Case = 0;
while(T--) {
Case++;
int n,m;
scanf("%d%d",&n,&m);
build(1,1,n);
ans = 0;
while(m--) {
int val;
scanf("%d",&val);
update(1,val);
}
printf("Case %d: %I64d\n",Case,ans);
}
return 0;
}