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.
在一个含有1-n的序列中,每次找到第Ki小的数,并把它删除。
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
第一个数T,表示测试数据的组数。
每组测试数据,第一行2个整数n和m,m表示操作的轮数。
接下来m行,每行一个整数k,表示要找出第k小的数,并把它删除。
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
树状数组记录数字是第几个,中间用二分查找,
可惜我二分全忘光了
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <string>
using namespace std;
//for(i=1;i<n;i++)
//scanf("%d",&n);
//printf("\n",);
//memset(num,0,sizeof(num));
long long tree[400000],ans;
int key[400000];
int main()
{
long long i,j,k,n,t,l,m,temp,tt;
scanf("%lld",&t);
for(l=1;l<=t;l++)
{
scanf("%lld%lld",&n,&m);
for(i=1;i<=n;i++)
{
k=i;
while(k<=n)
{
tree[k]+=1;
k+=((-k)&k);
}
}
ans=0;
for(i=1;i<=m;i++)
{
temp=0;
scanf("%lld",&j);
tt=j;
int st=0,en=n,mid;
while(st+1<en)
{
mid=(st+en)/2;
temp=0;
k=mid;
while(k>0)
{
temp+=tree[k];
k-=((-k)&k);
}
if(temp>=j)
{
en=mid;
}
else
{
st=mid;
}
}
k=en;
while(k<=n)
{
tree[k]-=1;
k+=((-k)&k);
}
ans+=en;
}
printf("Case %lld: %lld\n",l,ans);
memset(tree,0,sizeof(tree));
memset(key,0,sizeof(key));
}
//memset(num,0,sizeof(num));
return 0;
}