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的范围不大,可以用数组数组来查询,如果某个数置1,代表这个数被拿走了,二分去找第k小,因为有单调性,难度还行吧。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 262154
using namespace std;
int c[maxn];
int n,q;
int change(int x,int p)
{
for(;x<=n;x+=x&(-x))c[x]+=p;
}
int query(int x)
{
int ans=0;
for(;x;x-=x&-x)ans+=c[x];
return ans;
}
int getPos(int k)
{
int l=0,r=n-1;
while(l<=r)
{
int mid=(l+r)>>1;
int now=mid-query(mid);
if(now>=k)
r=mid-1;
else
l=mid+1;
}
return l;
}
int main()
{
int t;
cin>>t;
int cal=1;
while(t--)
{
cin>>n>>q;
memset(c,0,sizeof(c));
long long ans=0;
int x;
for(int i=0;i<q;i++)
{
scanf("%d",&x);
int num=getPos(x);
ans+=num;
change(num,1);
}
printf("Case %d: %lld\n",cal++,ans);
}
return 0;
}