#HDU - 4217 - Data Structure?
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 <= T <= 128
- 1 <= K <= N <= 262 144
- 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,m,n是数字的个数,即从1到n,m是m组询问,接下来m个数字k是问第k大的数字,每次被询问完之后,该数字就从数字串中删除。最后求询问的和。
还是建树,将val用来记录区间长度,如果k小于等于左区间长度就在左孩子里找,否则去右孩子找,在右孩子找的时候,要减去左边区间长度,因为要看在右孩子里的第几个。
#include <cstdio>
#include <vector>
#include <iostream>
#define ll long long
using namespace std;
const int maxn = 4e6 + 5;
struct node
{
ll l, r, val;
}p[maxn];
void build(ll l, ll r, ll cur)
{
p[cur].l = l, p[cur].r = r;
p[cur].val = r - l + 1;
if(l == r) return ;
ll m = (l + r) >> 1;
build(l, m, cur << 1);
build(m + 1, r, cur << 1 | 1);
}
ll query(ll pos, ll cur)
{
ll l = p[cur].l, r = p[cur].r;
p[cur].val--;
if(l == r) return l;
if(p[cur << 1].val >= pos) return query(pos, cur << 1);
else return query(pos - p[cur << 1].val, cur << 1 | 1);
}
int main()
{
ll t, ans, n, m;
scanf("%lld", &t);
for(int test = 1; test <= t; test++)
{
ans = 0;
scanf("%lld%lld", &n, &m);
build(1, n, 1);
for(int i = 0; i < m; i++)
{
ll pos;
scanf("%lld", &pos);
ans += query(pos, 1);
}
printf("Case %d: %lld\n", test, ans);
}
return 0;
}