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. 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

题意:1到n n个数,一共有 k 次操作,每次取出第 ki 小的数。问所有取出数字之和。

题解:线段树维护下区间还有多少数,更新到节点即可

 
#include<iostream>
#include<cstdio>
using namespace std;
const int N=270000;
typedef long long ll;
struct node{
	int l,r,sum;
}tree[N<<2];
int n,k;
void build(int l,int r,int cur)
{
	tree[cur].l=l;
	tree[cur].r=r;
	tree[cur].sum=r-l+1;
	if(l==r)return;
	int mid=(r+l)>>1;
	build(l,mid,cur<<1);
	build(mid+1,r,cur<<1|1); 
}
int query(int cur,int pos)
{
	if(tree[cur].l==tree[cur].r)
	{
		tree[cur].sum=0;
		return tree[cur].l;
	}
	int res;
	if(tree[cur<<1].sum>=pos) res=query(cur<<1,pos);
	else
	{
		res=query(cur<<1|1,pos-tree[cur<<1].sum);
	}
	tree[cur].sum=tree[cur<<1].sum+tree[cur<<1|1].sum;
	return res;
}
int main()
{
	int T,nn=1;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&k);
		build(1,n,1);
		ll ans=0;
		int x;
		for(int i=1;i<=k;i++)
		{
			scanf("%d",&x);
			ans+=query(1,x);
		}
		printf("Case %d: %lld\n",nn++,ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/mmk27_word/article/details/85222721