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.
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
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小的数。问所有取出数字之和。
思路:树状数组。开始所有位置都是1,如果有数字被去掉就-1。然后在查找第ki小的数字的时候,利用树状数组去进行求和,看数字个数为k时是第几个。
代码:
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
const int N = 277777;
int t, n, m, bit[N], num, i;
long long ans;
void add(int x, int v) {
while (x <= n) {
bit[x] += v;
x += (x&(-x));
}
}
int Sum(int k) {
int num = 0;
int x = 0;
for (int i = 18; i >= 0; i--) {
if (x + (1<<i) <= n && bit[x + (1<<i)] + num < k) {
x += (1<<i);
num += bit[x];
}
}
return x + 1;
}
void init() {
ans = 0;
memset(bit, 0, sizeof(bit));
scanf("%d%d", &n, &m);
for (i = 1; i <= n; i++)
add(i, 1);
for (i = 0; i < m; i++) {
scanf("%d", &num);
int s = Sum(num);
ans += s;
add(s, -1);
}
}
int main() {
int cas = 0;
scanf("%d", &t);
while (t--) {
init();
//printf("Case %d: %lld\n", ++cas, ans);
cout <<"Case "<<++cas<<": "<<ans<<endl;
}
return 0;
}